'use client'; import { memo, useEffect, useRef } from 'react'; import { gsap } from 'gsap'; import { cls } from '@/lib/utils'; interface CellWaveBackgroundProps { columns?: number; rows?: number; cellColor?: string; duration?: number; delay?: number; className?: string; } const CellWaveBackground = ({ columns = 5, rows = 24, cellColor = 'var(--color-background-accent)', duration = 0.25, delay = 1.25, className = '' }: CellWaveBackgroundProps) => { const containerRef = useRef(null); const cellRefs = useRef<(HTMLDivElement | null)[][]>([]); const timelinesRef = useRef([]); const setCellRef = (colIndex: number, cellIndex: number) => (el: HTMLDivElement | null) => { if (!cellRefs.current[colIndex]) { cellRefs.current[colIndex] = []; } cellRefs.current[colIndex][cellIndex] = el; }; const cellStyles = { backgroundColor: cellColor, boxShadow: `0px 0px 50px 16px color-mix(in srgb, ${cellColor} 12%, transparent), 0px 0px 7px 1px color-mix(in srgb, ${cellColor} 31%, transparent)` }; useEffect(() => { timelinesRef.current.forEach(tl => tl.kill()); timelinesRef.current = []; cellRefs.current.forEach((column, colIndex) => { const cells = [...column].filter(Boolean).reverse(); const timeline = gsap.timeline({ delay: delay * colIndex, repeat: -1, repeatDelay: 2 }); cells.forEach((cell, cellIndex) => { if (cell) { timeline.to(cell, { keyframes: [ { opacity: 0, duration: 0 }, { opacity: 0.05, duration: duration }, { opacity: 0.15, duration: duration }, { opacity: 0.25, duration: duration }, { opacity: 0.5, duration: duration }, { opacity: 0.25, duration: duration }, { opacity: 0.15, duration: duration }, { opacity: 0.05, duration: duration }, { opacity: 0, duration: duration } ], ease: 'none' }, cellIndex * duration); } }); timelinesRef.current.push(timeline); }); return () => { timelinesRef.current.forEach(tl => tl.kill()); }; }, [duration, delay, columns, rows]); return (