From 7bc42f8d489ebccb50ae0e4d9e139a514db67f8f Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Thu, 29 Jan 2026 22:09:19 +0000 Subject: [PATCH 1/2] Fix GradientBlinds scroll drift on mobile - Added isMobile detection (<= 768px) in GradientBlinds.tsx - Updated onPointerMove to calculate container-relative coordinates immediately on mobile - Updated animation loop to skip scroll-based target updates on mobile - Prevents spotlight from drifting across the background during scroll inertia on mobile devices Co-authored-by: ragusa-it <196988693+ragusa-it@users.noreply.github.com> --- src/components/effects/GradientBlinds.tsx | 27 ++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/components/effects/GradientBlinds.tsx b/src/components/effects/GradientBlinds.tsx index f53da04..e01a6bd 100644 --- a/src/components/effects/GradientBlinds.tsx +++ b/src/components/effects/GradientBlinds.tsx @@ -66,6 +66,7 @@ const GradientBlinds: React.FC = ({ const mouseTargetRef = useRef<[number, number]>([0, 0]); // Optimization: store raw pointer position (viewport coords) to decouple event handling from calculation const pointerPosRef = useRef<{ x: number; y: number } | null>(null); + const isMobileRef = useRef(false); const lastTimeRef = useRef(0); const firstResizeRef = useRef(true); const rectRef = useRef(null); @@ -283,6 +284,7 @@ void main() { const rect = container.getBoundingClientRect(); rectRef.current = rect; if (typeof window !== 'undefined') { + isMobileRef.current = window.innerWidth <= 768; scrollPosRef.current = { x: window.scrollX, y: window.scrollY }; } renderer.setSize(rect.width, rect.height); @@ -311,7 +313,30 @@ void main() { ro.observe(container); const onPointerMove = (e: PointerEvent) => { - pointerPosRef.current = { x: e.clientX, y: e.clientY }; + if (isMobileRef.current) { + // On mobile, calculate relative position immediately and store in target. + // This prevents the "ghost drift" effect when scrolling with inertia after lifting finger, + // because we won't be updating the target based on scroll position in the loop. + const scale = (renderer as unknown as { dpr?: number }).dpr || 1; + let x, y; + + if (rectRef.current) { + const dx = window.scrollX - scrollPosRef.current.x; + const dy = window.scrollY - scrollPosRef.current.y; + const rectLeft = rectRef.current.left - dx; + const rectTop = rectRef.current.top - dy; + x = (e.clientX - rectLeft) * scale; + y = (rectRef.current.height - (e.clientY - rectTop)) * scale; + } else { + const rect = canvas.getBoundingClientRect(); + x = (e.clientX - rect.left) * scale; + y = (rect.height - (e.clientY - rect.top)) * scale; + } + mouseTargetRef.current = [x, y]; + pointerPosRef.current = null; // Ensure loop doesn't override + } else { + pointerPosRef.current = { x: e.clientX, y: e.clientY }; + } }; const loop = (t: number) => { From c0d541d31b44b84c5915c82b9553a198e8a34b78 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Thu, 29 Jan 2026 22:30:40 +0000 Subject: [PATCH 2/2] Fix GradientBlinds scroll drift on mobile and address dampening regression - Added isMobile detection (<= 768px) in GradientBlinds.tsx - Updated onPointerMove to calculate container-relative coordinates immediately on mobile - Updated animation loop to skip scroll-based target updates on mobile - Fixed regression where disabling mouse dampening on mobile would freeze the spotlight - Prevents spotlight from drifting across the background during scroll inertia on mobile devices Co-authored-by: ragusa-it <196988693+ragusa-it@users.noreply.github.com> --- src/components/effects/GradientBlinds.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/effects/GradientBlinds.tsx b/src/components/effects/GradientBlinds.tsx index e01a6bd..9f3b787 100644 --- a/src/components/effects/GradientBlinds.tsx +++ b/src/components/effects/GradientBlinds.tsx @@ -376,7 +376,7 @@ void main() { cur[0] += (target[0] - cur[0]) * factor; cur[1] += (target[1] - cur[1]) * factor; } else { - if (pointerPosRef.current) { + if (pointerPosRef.current || isMobileRef.current) { uniforms.iMouse.value = mouseTargetRef.current; } lastTimeRef.current = t;