Refactor code structure for improved readability and maintainability
All checks were successful
Deploy / deploy (push) Successful in 10m26s

This commit is contained in:
bilalgursen
2026-07-30 03:17:12 +03:00
parent 40a1c8ef8e
commit dc6d894a37
33 changed files with 1574 additions and 651 deletions

View File

@@ -0,0 +1,74 @@
"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);
// Ham hız titrek olur; yay ile yumuşatınca bükülme salınıp yerine oturur
const smoothVelocity = useSpring(velocity, {
damping: 50,
stiffness: 420,
mass: 0.6,
});
// Ölü bölge: yavaş/ufak kaydırmalarda bükülme tamamen 0 kalır — transform
// hiç değişmediği için compositor'a kare başı iş çıkmaz. Eşik üstünde
// kareyle (ease-in) yükselir, 0,01°'lik adımlara yuvarlanır ki yayın
// mikro-salınımları her karede katmanı kirletmesin.
const skewY = useTransform(smoothVelocity, (v) => {
const DEADZONE = 500; // px/sn — bunun altı "normal gezinme" sayılır
const FULL = 2600; // px/sn — bu hızda maxSkew'e ulaşılır
const mag = Math.abs(v);
if (mag < DEADZONE) return 0;
const t = Math.min(1, (mag - DEADZONE) / (FULL - DEADZONE));
const s = t * t * maxSkew * Math.sign(v);
return Math.round(s * 100) / 100;
});
if (reduceMotion) {
return <div className={className}>{children}</div>;
}
return (
<ReactLenis root options={{ lerp: 0.09, anchors: true }}>
{/* willChange: bükülme 0'a döndüğünde dev katman GPU'dan düşüp
bir sonraki tekerlekte yeniden rasterize edilmesin */}
<motion.div
className={className}
style={{ skewY, willChange: "transform" }}
>
{children}
</motion.div>
</ReactLenis>
);
}