UNPKG

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.

80 lines (79 loc) 3.32 kB
// @ts-nocheck "use client"; import { jsx as _jsx } 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 ScrollPara({ paragraphs, direction = "bottom", startBlur = 10, offset = 50, className, containerClassName, textClassName, startOpacity = 0.1, stagger = 0.5, }) { const container = useRef(null); const textRefs = useRef([]); useGSAP(() => { gsap.registerPlugin(ScrollTrigger); const elements = textRefs.current.filter(Boolean); const totalElements = elements.length; if (totalElements === 0) return; const getInitialTransform = () => { switch (direction) { case "top": return { y: -offset, x: 0 }; case "left": return { x: -offset, y: 0 }; case "right": return { x: offset, y: 0 }; case "bottom": return { y: offset, x: 0 }; case "none": default: return { x: 0, y: 0 }; } }; // Set initial state elements.forEach((el) => { gsap.set(el, { ...getInitialTransform(), opacity: startOpacity, filter: `blur(${startBlur}px)`, }); }); const scrollTimeline = gsap.timeline({ scrollTrigger: { trigger: container.current, start: "top top", end: `+=${window.innerHeight * totalElements * 0.8}`, // Extended scroll duration based on items pin: true, scrub: 1, pinSpacing: true, anticipatePin: 1, }, }); elements.forEach((el, index) => { scrollTimeline.to(el, { x: 0, y: 0, opacity: 1, filter: "blur(0px)", duration: 1, ease: "power2.out", }, index * stagger); }); const resizeObserver = new ResizeObserver(() => { ScrollTrigger.refresh(); }); if (container.current) { resizeObserver.observe(container.current); } return () => { resizeObserver.disconnect(); scrollTimeline.kill(); }; }, { scope: container, dependencies: [direction, paragraphs.length, startOpacity, startBlur, offset, stagger], }); return (_jsx("div", { className: cn("relative w-full min-h-[100vh]", className), ref: container, children: _jsx("div", { className: "relative flex h-[100vh] w-full items-center justify-center overflow-hidden p-6 md:p-12", children: _jsx("div", { className: cn("relative w-full max-w-5xl flex flex-col gap-6 md:gap-10", containerClassName), children: paragraphs.map((text, i) => (_jsx("p", { className: cn("text-2xl md:text-5xl lg:text-6xl font-medium leading-tight tracking-tight text-white will-change-transform", textClassName), ref: (el) => { textRefs.current[i] = el; }, children: text }, i))) }) }) })); }