lightswind
Version:
A collection of beautifully crafted React Components, Blocks & Templates for Modern Developers. Create stunning web applications effortlessly by using our 160+ professional and animated react components.
45 lines (44 loc) • 2.59 kB
JavaScript
// @ts-nocheck
"use client";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useGSAP } from "@gsap/react";
import gsap from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
import { useRef } from "react";
import { cn } from "../../lib/utils";
export function ScrollPara3D({ lines, className, containerClassName, textClassName, perspective = 600, angle = 50, scrubSpeed = 1.2, fontSize = 3.5, }) {
const sectionRef = useRef(null);
const contentRef = useRef(null);
useGSAP(() => {
gsap.registerPlugin(ScrollTrigger);
if (!contentRef.current || !sectionRef.current)
return;
const contentHeight = contentRef.current.offsetHeight;
const windowHeight = window.innerHeight;
const tl = gsap.timeline({
scrollTrigger: {
trigger: sectionRef.current,
start: "top top",
end: `+=${contentHeight * scrubSpeed}`,
pin: true,
scrub: 1,
anticipatePin: 1,
},
});
// Start just below so text is immediately visible on scroll
tl.fromTo(contentRef.current, { y: windowHeight * 0.3 }, { y: -contentHeight, ease: "none" });
return () => { tl.kill(); };
}, { dependencies: [lines.length, perspective, angle, scrubSpeed, fontSize] });
return (_jsxs("div", { ref: sectionRef, className: cn("relative w-full h-screen overflow-hidden bg-background", className), style: { perspective: `${perspective}px` }, children: [_jsx("div", { className: "absolute inset-0 z-10 pointer-events-none", style: {
background: "linear-gradient(to bottom, var(--background) 0%, transparent 15%, transparent 85%, var(--background) 100%)",
} }), _jsx("div", { style: {
position: "absolute",
inset: 0,
display: "flex",
alignItems: "flex-end",
justifyContent: "center",
transformStyle: "preserve-3d",
transform: `rotateX(${angle}deg)`,
transformOrigin: "center bottom",
}, children: _jsx("div", { ref: contentRef, className: cn("w-full flex flex-col items-center justify-start", containerClassName), style: { willChange: "transform" }, children: lines.map((line, i) => (_jsx("p", { className: cn("w-full text-center font-black uppercase text-primary tracking-tighter leading-tight", textClassName), style: { fontSize: `${fontSize}rem` }, children: line }, i))) }) })] }));
}