From 6bdb3c80af9743d303ab3db2e5cd8517ee025c1c Mon Sep 17 00:00:00 2001 From: hamid zarghami Date: Mon, 29 Jun 2026 09:52:20 +0330 Subject: [PATCH] parallax --- src/app/[name]/(Main)/[id]/page.tsx | 49 +++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/src/app/[name]/(Main)/[id]/page.tsx b/src/app/[name]/(Main)/[id]/page.tsx index 4118f8f..1998e2d 100644 --- a/src/app/[name]/(Main)/[id]/page.tsx +++ b/src/app/[name]/(Main)/[id]/page.tsx @@ -10,7 +10,7 @@ import { glassSurface, glassSurfaceCard, glassSurfaceFlat } from "@/lib/styles/g import { motion } from "framer-motion"; import { ArrowLeft, Clock, Cup, Heart, TruckTick } from "iconsax-react"; import { useParams, useRouter } from "next/navigation"; -import { useEffect, useMemo, useState } from "react"; +import { useEffect, useMemo, useRef, useState } from "react"; import { useGetProfile } from "../../(Profile)/profile/hooks/userProfileData"; import { useGetAbout } from "../about/hooks/useAboutData"; import { useGetFood, useToggleFavorite } from "./hooks/useFoodData"; @@ -26,6 +26,8 @@ function FoodPage({}: Props) { const { items, addToCart, removeFromCart } = useCart(); const [isFavorite, setIsFavorite] = useState(false); const { mutate: toggleFavorite } = useToggleFavorite(); + const pageRef = useRef(null); + const imageRef = useRef(null); const foodId = food?.data?.id || (id as string); const quantity = useMemo(() => { @@ -80,6 +82,33 @@ function FoodPage({}: Props) { } }, [food?.data?.isFavorite]); + useEffect(() => { + const scrollEl = pageRef.current?.closest("main"); + const imageEl = imageRef.current; + if (!scrollEl || !imageEl) return; + + const desktopQuery = window.matchMedia("(min-width: 1024px)"); + const PARALLAX_FACTOR = 0.35; + + const applyParallax = () => { + if (desktopQuery.matches) { + imageEl.style.transform = ""; + return; + } + imageEl.style.transform = `translate3d(0, ${scrollEl.scrollTop * PARALLAX_FACTOR}px, 0) scale(1.12)`; + }; + + scrollEl.addEventListener("scroll", applyParallax, { passive: true }); + desktopQuery.addEventListener("change", applyParallax); + applyParallax(); + + return () => { + scrollEl.removeEventListener("scroll", applyParallax); + desktopQuery.removeEventListener("change", applyParallax); + imageEl.style.transform = ""; + }; + }, [food?.data?.id]); + if (isLoading) { return (
@@ -125,20 +154,26 @@ function FoodPage({}: Props) { }; return ( -
+
{/* eslint-disable-next-line @next/next/no-img-element */} {foodName} { event.currentTarget.src = "/assets/images/no-image.png"; }} /> -
+
{categoryName || "-"}
{foodName}