mirror of
https://github.com/Since-3/Kumasy-Marketing.git
synced 2026-10-12 19:51:17 +00:00
65 lines
1.8 KiB
TypeScript
65 lines
1.8 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect } from "react";
|
|
import Lenis from "lenis";
|
|
import { useReducedMotion } from "./motion";
|
|
|
|
/**
|
|
* Momentum scrolling. The wheel no longer maps 1:1 to scroll position —
|
|
* it feeds a spring that eases toward the target, so every scroll-linked
|
|
* animation on the page inherits the same softened motion.
|
|
*
|
|
* Disabled entirely under prefers-reduced-motion: hijacking the scroll is
|
|
* exactly what that preference asks us not to do.
|
|
*/
|
|
export function SmoothScroll() {
|
|
const reduced = useReducedMotion();
|
|
|
|
useEffect(() => {
|
|
if (reduced) return;
|
|
|
|
const lenis = new Lenis({
|
|
// Slightly longer than default so the easing is felt, not just seen.
|
|
duration: 1.1,
|
|
easing: (t: number) => 1 - Math.pow(1 - t, 3),
|
|
// Touch devices keep their native scrolling; overriding it there
|
|
// fights the platform and breaks momentum handoff.
|
|
smoothWheel: true,
|
|
touchMultiplier: 1.6,
|
|
});
|
|
|
|
let frame = 0;
|
|
const raf = (time: number) => {
|
|
lenis.raf(time);
|
|
frame = requestAnimationFrame(raf);
|
|
};
|
|
frame = requestAnimationFrame(raf);
|
|
|
|
// In-page anchors must go through Lenis, or they jump past the easing.
|
|
const onClick = (event: MouseEvent) => {
|
|
const anchor = (event.target as HTMLElement | null)?.closest?.(
|
|
'a[href^="#"]',
|
|
) as HTMLAnchorElement | null;
|
|
if (!anchor) return;
|
|
|
|
const id = anchor.getAttribute("href");
|
|
if (!id || id === "#") return;
|
|
|
|
const target = document.querySelector(id);
|
|
if (!target) return;
|
|
|
|
event.preventDefault();
|
|
lenis.scrollTo(target as HTMLElement, { offset: -104 });
|
|
};
|
|
|
|
document.addEventListener("click", onClick);
|
|
|
|
return () => {
|
|
document.removeEventListener("click", onClick);
|
|
cancelAnimationFrame(frame);
|
|
lenis.destroy();
|
|
};
|
|
}, [reduced]);
|
|
|
|
return null;
|
|
}
|