From f9dd6d6b3ef877ce619ab998efad469602b4a7bb Mon Sep 17 00:00:00 2001 From: bender Date: Sun, 8 Mar 2026 21:27:52 +0000 Subject: [PATCH] Update src/components/cardStack/hooks/useCardAnimation.ts --- .../cardStack/hooks/useCardAnimation.ts | 203 +++--------------- 1 file changed, 35 insertions(+), 168 deletions(-) diff --git a/src/components/cardStack/hooks/useCardAnimation.ts b/src/components/cardStack/hooks/useCardAnimation.ts index 4331477..719b31a 100644 --- a/src/components/cardStack/hooks/useCardAnimation.ts +++ b/src/components/cardStack/hooks/useCardAnimation.ts @@ -1,187 +1,54 @@ -import { useRef } from "react"; -import { useGSAP } from "@gsap/react"; -import gsap from "gsap"; -import { ScrollTrigger } from "gsap/ScrollTrigger"; -import type { CardAnimationType, GridVariant } from "../types"; -import { useDepth3DAnimation } from "./useDepth3DAnimation"; +'use client'; + +import { useEffect, useRef } from 'react'; +import gsap from 'gsap'; +import { ScrollTrigger } from 'gsap/ScrollTrigger'; gsap.registerPlugin(ScrollTrigger); -interface UseCardAnimationProps { - animationType: CardAnimationType | "depth-3d"; - itemCount: number; - isGrid?: boolean; - supports3DAnimation?: boolean; - gridVariant?: GridVariant; - useIndividualTriggers?: boolean; +interface UseCardAnimationReturn { + isMobile: boolean; + itemRefs: React.RefObject[]; } -export const useCardAnimation = ({ - animationType, - itemCount, - isGrid = true, - supports3DAnimation = false, - gridVariant, - useIndividualTriggers = false -}: UseCardAnimationProps) => { - const itemRefs = useRef<(HTMLElement | null)[]>([]); - const containerRef = useRef(null); - const perspectiveRef = useRef(null); - const bottomContentRef = useRef(null); +export const useCardAnimation = (itemCount: number): UseCardAnimationReturn => { + const itemRefs = useRef[]>([]); + const isMobile = typeof window !== 'undefined' && window.innerWidth < 768; - // Enable 3D effect only when explicitly supported and conditions are met - const { isMobile } = useDepth3DAnimation({ - itemRefs, - containerRef, - perspectiveRef, - isEnabled: animationType === "depth-3d" && isGrid && supports3DAnimation && gridVariant === "uniform-all-items-equal", - }); - - // Use scale-rotate as fallback when depth-3d conditions aren't met - const effectiveAnimationType = - animationType === "depth-3d" && (isMobile || !isGrid || gridVariant !== "uniform-all-items-equal") - ? "scale-rotate" - : animationType; - - useGSAP(() => { - if (effectiveAnimationType === "none" || effectiveAnimationType === "depth-3d" || itemRefs.current.length === 0) return; - - const items = itemRefs.current.filter((el) => el !== null); - // Include bottomContent in animation if it exists - if (bottomContentRef.current) { - items.push(bottomContentRef.current); + useEffect(() => { + itemRefs.current = itemRefs.current.slice(0, itemCount); + for (let i = itemRefs.current.length; i < itemCount; i++) { + itemRefs.current[i] = { current: null }; } + }, [itemCount]); - if (effectiveAnimationType === "opacity") { - if (useIndividualTriggers) { - items.forEach((item) => { + useEffect(() => { + if (!isMobile) { + itemRefs.current.forEach((ref, index) => { + if (ref.current) { gsap.fromTo( - item, - { opacity: 0 }, + ref.current, + { opacity: 0, y: 20 }, { opacity: 1, - duration: 1.25, - ease: "sine", + y: 0, + duration: 0.6, + delay: index * 0.1, scrollTrigger: { - trigger: item, - start: "top 80%", - toggleActions: "play none none none", + trigger: ref.current, + start: 'top 80%', + end: 'top 20%', + scrub: false, }, } ); - }); - } else { - gsap.fromTo( - items, - { opacity: 0 }, - { - opacity: 1, - duration: 1.25, - stagger: 0.15, - ease: "sine", - scrollTrigger: { - trigger: items[0], - start: "top 80%", - toggleActions: "play none none none", - }, - } - ); - } - } else if (effectiveAnimationType === "slide-up") { - items.forEach((item, index) => { - gsap.fromTo( - item, - { opacity: 0, yPercent: 15 }, - { - opacity: 1, - yPercent: 0, - duration: 1, - delay: useIndividualTriggers ? 0 : index * 0.15, - ease: "sine", - scrollTrigger: { - trigger: useIndividualTriggers ? item : items[0], - start: "top 80%", - toggleActions: "play none none none", - }, - } - ); + } }); - } else if (effectiveAnimationType === "scale-rotate") { - if (useIndividualTriggers) { - items.forEach((item) => { - gsap.fromTo( - item, - { scaleX: 0, rotate: 10 }, - { - scaleX: 1, - rotate: 0, - duration: 1, - ease: "power3", - scrollTrigger: { - trigger: item, - start: "top 80%", - toggleActions: "play none none none", - }, - } - ); - }); - } else { - gsap.fromTo( - items, - { scaleX: 0, rotate: 10 }, - { - scaleX: 1, - rotate: 0, - duration: 1, - stagger: 0.15, - ease: "power3", - scrollTrigger: { - trigger: items[0], - start: "top 80%", - toggleActions: "play none none none", - }, - } - ); - } - } else if (effectiveAnimationType === "blur-reveal") { - if (useIndividualTriggers) { - items.forEach((item) => { - gsap.fromTo( - item, - { opacity: 0, filter: "blur(10px)" }, - { - opacity: 1, - filter: "blur(0px)", - duration: 1.2, - ease: "power2.out", - scrollTrigger: { - trigger: item, - start: "top 80%", - toggleActions: "play none none none", - }, - } - ); - }); - } else { - gsap.fromTo( - items, - { opacity: 0, filter: "blur(10px)" }, - { - opacity: 1, - filter: "blur(0px)", - duration: 1.2, - stagger: 0.15, - ease: "power2.out", - scrollTrigger: { - trigger: items[0], - start: "top 80%", - toggleActions: "play none none none", - }, - } - ); - } } - }, [effectiveAnimationType, itemCount, useIndividualTriggers]); + }, [isMobile]); - return { itemRefs, containerRef, perspectiveRef, bottomContentRef }; + return { + isMobile, + itemRefs: itemRefs.current, + }; };