This commit is contained in:
Iliyan Angelov
2025-11-24 03:52:08 +02:00
parent dfcaebaf8c
commit 366f28677a
18241 changed files with 865352 additions and 567 deletions

View 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;