import { useRef, useEffect } from "react"; import { motion } from "motion/react"; import { ArrowRight } from "lucide-react"; import gsap from "gsap"; import { ScrollTrigger } from "gsap/ScrollTrigger"; import ImageOrVideo from "@/components/ui/ImageOrVideo"; import HeroBackgroundSlot from "@/components/ui/HeroBackgroundSlot"; import TextAnimation from "@/components/ui/TextAnimation"; import { useButtonClick } from "@/hooks/useButtonClick"; gsap.registerPlugin(ScrollTrigger); interface HeroWorkScrollStackProps { tag: string; title: string; titleHighlight: string; description: string; descriptionMuted: string; primaryButton: { text: string; href: string; avatarSrc: string; avatarLabel: string }; sectionTag: string; sectionTitle: string; sectionDescription: string; items: [ { title: string; description: string; imageSrc: string; tag: string }, { title: string; description: string; imageSrc: string; tag: string }, { title: string; description: string; imageSrc: string; tag: string } ]; secondaryButton?: { text: string; href: string }; heroAnimationDelay?: number; } const HeroWorkScrollStack = ({ tag, title, titleHighlight, description, descriptionMuted, primaryButton, sectionTag, sectionTitle, sectionDescription, items, secondaryButton, heroAnimationDelay, }: HeroWorkScrollStackProps) => { const animationRef = useRef(null); const placeholderRef = useRef(null); const card1Ref = useRef(null); const card2Ref = useRef(null); const card3Ref = useRef(null); const handlePrimaryClick = useButtonClick(primaryButton.href); const handleSecondaryClick = useButtonClick(secondaryButton?.href || "#"); useEffect(() => { const isDesktop = window.matchMedia("(min-width: 768px)").matches; const ctx = gsap.context(() => { const cardRefs = [card1Ref.current, card2Ref.current, card3Ref.current]; const placeholder = placeholderRef.current; if (!placeholder) return; const placeholderRect = placeholder.getBoundingClientRect(); const placeholderCenterY = placeholderRect.top + placeholderRect.height / 2; if (isDesktop) { // DESKTOP: Scrub animation tied to scroll position const xOffsets = ["32rem", "14.5rem", "-1.8rem"]; const yAdjustments = [0, -48, 0]; const rotations = [-5, 0, 5]; const scales = [1.35, 1.3, 1.25]; const zIndexes = [30, 20, 10]; const tl = gsap.timeline({ scrollTrigger: { trigger: animationRef.current, start: "top top", end: "bottom bottom", scrub: 1, }, }); cardRefs.forEach((card, i) => { if (!card) return; const cardRect = card.getBoundingClientRect(); const cardCenterY = cardRect.top + cardRect.height / 2; const yOffset = placeholderCenterY - cardCenterY; gsap.set(card, { x: xOffsets[i], y: yOffset + yAdjustments[i], rotation: rotations[i], scale: scales[i], zIndex: zIndexes[i], willChange: "transform", force3D: true, }); tl.to(card, { x: 0, y: 0, rotation: 0, scale: 1, duration: 0.4, ease: "none" }, 0); tl.to(card, { zIndex: 1, duration: 0.1, ease: "none" }, 0.3); }); } else { // MOBILE: Toggle animation - play/reverse on scroll const xOffsets = ["2.5rem", "0.5rem", "-1rem"]; const yAdjustments = [-10, -30, 10]; const rotations = [-5, 0, 5]; const scales = [0.65, 0.7, 0.75]; const zIndexes = [30, 20, 10]; cardRefs.forEach((card, i) => { if (!card) return; const cardRect = card.getBoundingClientRect(); const cardCenterY = cardRect.top + cardRect.height / 2; const yOffset = placeholderCenterY - cardCenterY; gsap.set(card, { x: xOffsets[i], y: yOffset + yAdjustments[i], rotation: rotations[i], scale: scales[i], zIndex: zIndexes[i], willChange: "transform", force3D: true, }); gsap.to(card, { x: 0, y: 0, rotation: 0, scale: 1, duration: 1.2, ease: "power2.inOut", scrollTrigger: { trigger: placeholder, start: "top 35%", toggleActions: "play none none reverse", }, }); }); } }, animationRef); return () => ctx.revert(); }, []); return (

{tag}

{title}{" "} {titleHighlight}

{description}{" "} {descriptionMuted}

+
{primaryButton.avatarLabel}
{primaryButton.text}

{sectionTag}

{items.map((item, index) => { const cardRef = index === 0 ? card1Ref : index === 1 ? card2Ref : card3Ref; return (
{item.tag}

{item.title}. {item.description}

); })}
{secondaryButton && ( )}
); }; export default HeroWorkScrollStack;