From 408f968e96b4f5e78a8348b1d78e5ffec5ac833c Mon Sep 17 00:00:00 2001 From: ssbg04 Date: Thu, 3 Sep 2026 23:47:49 +0800 Subject: [PATCH] fix: use named createImageUrlBuilder from @sanity/image-url, make background parallax vibrant and clearly visible --- src/components/Background.tsx | 139 +++++++++++++++++++--------------- src/lib/sanity.ts | 4 +- 2 files changed, 80 insertions(+), 63 deletions(-) diff --git a/src/components/Background.tsx b/src/components/Background.tsx index 9398a91..2979b62 100644 --- a/src/components/Background.tsx +++ b/src/components/Background.tsx @@ -3,101 +3,118 @@ import { motion, useScroll, useTransform, useSpring } from 'framer-motion'; export default function Background() { const [mounted, setMounted] = useState(false); - const [isLowTierOrMobile, setIsLowTierOrMobile] = useState(false); + const [reducedMotion, setReducedMotion] = useState(false); - // Mouse spring for smooth desktop lighting tracking - const mouseX = useSpring(0, { stiffness: 40, damping: 25 }); - const mouseY = useSpring(0, { stiffness: 40, damping: 25 }); + // Mouse spring for smooth desktop ambient lighting tracking + const mouseX = useSpring(0, { stiffness: 50, damping: 28 }); + const mouseY = useSpring(0, { stiffness: 50, damping: 28 }); - // Window scroll progress + // Native window scroll tracking const { scrollY } = useScroll(); - // Decoupled scroll parallax for each ambient layer - const gridY = useTransform(scrollY, [0, 3000], [0, 90]); - const orb1ScrollY = useTransform(scrollY, [0, 3000], [0, 260]); - const orb1ScrollX = useTransform(scrollY, [0, 3000], [0, 80]); + // Distinct parallax movement across scroll depths + // Layer 1: Dot Matrix Grid (drifts downward with scroll) + const gridY = useTransform(scrollY, [0, 2000], [0, 140]); - const orb2ScrollY = useTransform(scrollY, [0, 3000], [0, -280]); - const orb2ScrollX = useTransform(scrollY, [0, 3000], [0, -70]); + // Layer 2: Primary Indigo-Blue Orb (moves down and right) + const orb1ScrollY = useTransform(scrollY, [0, 2000], [0, 380]); + const orb1ScrollX = useTransform(scrollY, [0, 2000], [0, 120]); - const orb3ScrollY = useTransform(scrollY, [0, 3000], [0, -160]); + // Layer 3: Secondary Violet-Cyan Orb (moves up and counter-left) + const orb2ScrollY = useTransform(scrollY, [0, 2000], [0, -320]); + const orb2ScrollX = useTransform(scrollY, [0, 2000], [0, -100]); + + // Layer 4: Emerald-Teal Accent Glow (floats diagonally) + const orb3ScrollY = useTransform(scrollY, [0, 2000], [0, -220]); + const orb3ScrollX = useTransform(scrollY, [0, 2000], [0, 80]); + + // Layer 5: Floating Geometric Depth Rings (distinct, noticeable parallax markers) + const ring1Y = useTransform(scrollY, [0, 2000], [0, 450]); + const ring2Y = useTransform(scrollY, [0, 2000], [0, -280]); useEffect(() => { setMounted(true); - const isCoarse = window.matchMedia('(pointer: coarse)').matches; - const prefersReduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches; - const isLowTier = document.documentElement.dataset.tier === 'low'; - - if (isCoarse || prefersReduced || isLowTier) { - setIsLowTierOrMobile(true); + if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) { + setReducedMotion(true); return; } const handleMouseMove = (e: MouseEvent) => { const centerX = window.innerWidth / 2; const centerY = window.innerHeight / 2; - // Gentle offset (max ~35px) - mouseX.set((e.clientX - centerX) * 0.04); - mouseY.set((e.clientY - centerY) * 0.04); + // Responsive mouse parallax offset (up to ~55px) + mouseX.set((e.clientX - centerX) * 0.06); + mouseY.set((e.clientY - centerY) * 0.06); }; window.addEventListener('mousemove', handleMouseMove, { passive: true }); return () => window.removeEventListener('mousemove', handleMouseMove); }, [mouseX, mouseY]); - // Static fallback during SSR or for low-end mobile/reduced-motion users - if (!mounted || isLowTierOrMobile) { - return ( -