"use client"; import { type ReactNode } from "react"; import { ReactLenis } from "lenis/react"; import { motion, useReducedMotion, useScroll, useSpring, useTransform, useVelocity, } from "motion/react"; /** * Vitrin sayfalarının akışkan scroll efekti: Lenis ile lerp'li (yavaşlatılmış, * momentumlu) kaydırma + scroll hızına bağlı içerik bükülmesi (skew). * Hızlı kaydırdıkça sayfa hafifçe yana yatar, durunca yayla yerine oturur. * * Sohbet ve liste gibi iç scroll alanı olan uygulama sayfalarında KULLANMA — * Lenis tekerlek olayını sayfaya yönlendirdiği için iç scroll'u bozar, * transform da `fixed` konumlu çocukları koparır. * * Hareket azaltılmışsa hem yumuşatma hem bükülme tamamen kapalıdır. */ export function ScrollFlow({ children, className, maxSkew = 3, }: { children: ReactNode; className?: string; /** Derece cinsinden en fazla bükülme açısı. */ maxSkew?: number; }) { const reduceMotion = useReducedMotion(); const { scrollY } = useScroll(); const velocity = useVelocity(scrollY); // Önce hızı kesintisiz bir hedef açıya dönüştür, sonra doğrudan görünen // açıyı yumuşat. Böylece eşik/clamp kaynaklı ani hız değişimleri yaya girmez. const targetSkew = useTransform(velocity, (v) => { const RESPONSE = 1800; return Math.tanh(v / RESPONSE) * maxSkew; }); const smoothSkew = useSpring(targetSkew, { stiffness: 240, damping: 26, mass: 0.7, restDelta: 0.005, restSpeed: 0.01, }); // Yuvarlama görsel basamaklanma üretir. Tam hassasiyetle çiz; yalnızca açı // algılanamayacak kadar küçüldüğünde transform'u kaldırarak dev sayfa // katmanının GPU belleğinde boşuna tutulmasını önle. const transform = useTransform(smoothSkew, (v) => { if (Math.abs(v) < 0.01) return "none"; return `skewY(${v}deg)`; }); // Hareket azaltılmışsa da AYNI ağaç render edilir (server/client farklı // ağaç hydration uyumsuzluğu yaratıyordu); efektler koşullu kapatılır: // Lenis tekerlek yumuşatması kapalı, skew transform'u hiç bağlanmaz. return ( {children} ); }