update
This commit is contained in:
107
frontEnd/components/shared/layout/animations/SmoothScroll.tsx
Normal file
107
frontEnd/components/shared/layout/animations/SmoothScroll.tsx
Normal file
@@ -0,0 +1,107 @@
|
||||
"use client";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { gsap } from "gsap";
|
||||
import { ScrollTrigger } from "gsap/dist/ScrollTrigger";
|
||||
import Lenis from "lenis";
|
||||
import { usePathname } from "next/navigation";
|
||||
|
||||
const SmoothScroll = () => {
|
||||
const lenisRef = useRef<Lenis | null>(null);
|
||||
const pathname = usePathname();
|
||||
const [isNavigating, setIsNavigating] = useState(false);
|
||||
|
||||
// Handle pathname changes - PRIORITY 1
|
||||
useEffect(() => {
|
||||
setIsNavigating(true);
|
||||
|
||||
// Stop Lenis completely
|
||||
if (lenisRef.current) {
|
||||
lenisRef.current.stop();
|
||||
lenisRef.current.scrollTo(0, { immediate: true, force: true, lock: true });
|
||||
}
|
||||
|
||||
// Force scroll to top with all methods
|
||||
window.scrollTo({ top: 0, left: 0, behavior: 'auto' });
|
||||
window.scrollTo(0, 0);
|
||||
document.documentElement.scrollTop = 0;
|
||||
document.body.scrollTop = 0;
|
||||
|
||||
// Keep forcing scroll for a brief period
|
||||
const forceScroll = () => {
|
||||
window.scrollTo(0, 0);
|
||||
document.documentElement.scrollTop = 0;
|
||||
document.body.scrollTop = 0;
|
||||
};
|
||||
|
||||
// Force scroll every 16ms (one frame) for 200ms
|
||||
const intervalId = setInterval(forceScroll, 16);
|
||||
|
||||
// After navigation is settled, restart Lenis
|
||||
const restartTimeout = setTimeout(() => {
|
||||
clearInterval(intervalId);
|
||||
|
||||
if (lenisRef.current) {
|
||||
lenisRef.current.scrollTo(0, { immediate: true, force: true });
|
||||
lenisRef.current.start();
|
||||
}
|
||||
|
||||
setIsNavigating(false);
|
||||
|
||||
// Final scroll enforcement
|
||||
window.scrollTo(0, 0);
|
||||
document.documentElement.scrollTop = 0;
|
||||
document.body.scrollTop = 0;
|
||||
}, 200);
|
||||
|
||||
return () => {
|
||||
clearInterval(intervalId);
|
||||
clearTimeout(restartTimeout);
|
||||
};
|
||||
}, [pathname]);
|
||||
|
||||
// Initialize Lenis - PRIORITY 2
|
||||
useEffect(() => {
|
||||
gsap.registerPlugin(ScrollTrigger);
|
||||
|
||||
const lenis = new Lenis({
|
||||
duration: 1.2,
|
||||
easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)),
|
||||
orientation: 'vertical',
|
||||
gestureOrientation: 'vertical',
|
||||
smoothWheel: true,
|
||||
wheelMultiplier: 1,
|
||||
smoothTouch: false,
|
||||
touchMultiplier: 2,
|
||||
infinite: false,
|
||||
});
|
||||
|
||||
lenisRef.current = lenis;
|
||||
|
||||
// Force initial scroll to top
|
||||
lenis.scrollTo(0, { immediate: true, force: true });
|
||||
window.scrollTo(0, 0);
|
||||
|
||||
// Connect to GSAP ticker
|
||||
const tickerCallback = (time: number) => {
|
||||
if (!isNavigating) {
|
||||
lenis.raf(time * 350);
|
||||
}
|
||||
};
|
||||
|
||||
gsap.ticker.add(tickerCallback);
|
||||
gsap.ticker.lagSmoothing(0);
|
||||
|
||||
// Sync with ScrollTrigger
|
||||
lenis.on('scroll', ScrollTrigger.update);
|
||||
|
||||
return () => {
|
||||
lenis.destroy();
|
||||
gsap.ticker.remove(tickerCallback);
|
||||
lenisRef.current = null;
|
||||
};
|
||||
}, []);
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
export default SmoothScroll;
|
||||
Reference in New Issue
Block a user