"use client"; import React, { useState, useEffect, useRef, useCallback } from 'react'; import { ArrowUp } from 'lucide-react'; import gsap from 'gsap'; import { ImageWave } from '@/components/ui/ImageWave'; interface AnimationStageProps { shouldStart: boolean; onComplete: () => void; } // 动画1:模拟输入和点击 const InputAnimation: React.FC = ({ shouldStart, onComplete }) => { const containerRef = useRef(null); const inputRef = useRef(null); const cursorRef = useRef(null); const buttonRef = useRef(null); const mouseRef = useRef(null); const [displayText, setDisplayText] = useState(''); const demoText = "a cute capybara with an orange on its head"; useEffect(() => { if (!shouldStart || !containerRef.current) return; // 重置状态 setDisplayText(''); const tl = gsap.timeline({ onComplete: () => { setTimeout(onComplete, 500); } }); // 1. 显示输入框和鼠标 tl.fromTo([inputRef.current, mouseRef.current], { scale: 0.9, opacity: 0 }, { scale: 1, opacity: 1, duration: 0.3, ease: "back.out(1.7)", stagger: 0.1 }); // 2. 鼠标移动到输入框中心 tl.to(mouseRef.current, { x: 20, y: 0, duration: 0.3 }); // 3. 输入框聚焦效果 tl.to(inputRef.current, { scale: 1.02, boxShadow: '0 0 0 2px rgba(59, 130, 246, 0.5)', duration: 0.2 }); // 4. 打字动画 const typingDuration = demoText.length * 0.05; tl.to({}, { duration: typingDuration, onUpdate: function() { const progress = this.progress(); const targetChar = Math.floor(progress * demoText.length); setDisplayText(demoText.slice(0, targetChar)); } }); // 6. 鼠标移动到按钮位置(调整移动时间和缓动函数) tl.to(mouseRef.current, { x: 650, y: 0, duration: 0.8, ease: "power2.inOut" }); // 7. 等待一小段时间 tl.to({}, { duration: 0.2 }); // 8. 点击效果 tl.to(mouseRef.current, { scale: 0.8, duration: 0.1, yoyo: true, repeat: 1 }).to(buttonRef.current, { scale: 0.95, duration: 0.1, yoyo: true, repeat: 1 }, "<"); // 9. 等待一小段时间 tl.to({}, { duration: 0.3 }); // 10. 整体淡出 tl.to(containerRef.current, { opacity: 0, y: -20, duration: 0.3 }); }, [shouldStart, onComplete]); return (
{displayText}
); }; // 动画2:ImageWave 动画展示 const WaveAnimation: React.FC = ({ shouldStart, onComplete }) => { const containerRef = useRef(null); const [showWave, setShowWave] = useState(false); const [autoAnimate, setAutoAnimate] = useState(false); const imageUrls = [ 'https://d3phaj0sisr2ct.cloudfront.net/app/gen4/object-reference/welcome-ref-1.jpg', 'https://d3phaj0sisr2ct.cloudfront.net/app/gen4/object-reference/welcome-ref-2.jpg', 'https://d3phaj0sisr2ct.cloudfront.net/app/gen4/object-reference/welcome-ref-3.jpg', 'https://d3phaj0sisr2ct.cloudfront.net/app/gen4/object-reference/welcome-ref-4.jpg', 'https://d3phaj0sisr2ct.cloudfront.net/app/gen4/object-reference/welcome-ref-1.jpg', 'https://d3phaj0sisr2ct.cloudfront.net/app/gen4/object-reference/welcome-ref-2.jpg', 'https://d3phaj0sisr2ct.cloudfront.net/app/gen4/object-reference/welcome-ref-3.jpg', 'https://d3phaj0sisr2ct.cloudfront.net/app/gen4/object-reference/welcome-ref-4.jpg', 'https://d3phaj0sisr2ct.cloudfront.net/app/gen4/object-reference/welcome-ref-3.jpg', 'https://d3phaj0sisr2ct.cloudfront.net/app/gen4/object-reference/welcome-ref-2.jpg', 'https://d3phaj0sisr2ct.cloudfront.net/app/gen4/object-reference/welcome-ref-1.jpg', ]; useEffect(() => { if (!shouldStart) { setShowWave(false); setAutoAnimate(false); return; } // 显示 ImageWave setShowWave(true); // 延迟开始自动动画 const startTimeout = setTimeout(() => { setAutoAnimate(true); }, 300); return () => { clearTimeout(startTimeout); }; }, [shouldStart]); const handleAnimationComplete = () => { // 动画完成后淡出并触发完成回调 gsap.to(containerRef.current, { opacity: 0, scale: 0.9, duration: 0.3, onComplete: () => { setAutoAnimate(false); setShowWave(false); onComplete(); } }); }; return (
); }; // 动画3:图片墙打破,显示视频 const FinalAnimation: React.FC = ({ shouldStart, onComplete }) => { const containerRef = useRef(null); const videoRef = useRef(null); const [showVideo, setShowVideo] = useState(false); const videoUrl = 'https://cdn.qikongjian.com/videos/1750385931_99a8fb42-af89-4ae9-841a-a49869f026bd_text_to_video_0.mp4'; useEffect(() => { if (!shouldStart || !containerRef.current) return; const tl = gsap.timeline({ onComplete: () => { setTimeout(() => { // 淡出视频 gsap.to(containerRef.current, { opacity: 0, scale: 0.9, duration: 0.3, onComplete }); }, 3000); } }); // 显示容器 tl.fromTo(containerRef.current, { opacity: 0, scale: 0.9 }, { opacity: 1, scale: 1, duration: 0.3 } ); // 显示视频 setShowVideo(true); }, [shouldStart, onComplete]); return (
{showVideo && (
); }; // 主组件 export const EmptyStateAnimation = ({ className }: { className: string }) => { const [currentStage, setCurrentStage] = useState<'input' | 'wave' | 'final'>('input'); const [animationCycle, setAnimationCycle] = useState(0); const [isReady, setIsReady] = useState(true); const handleStageComplete = useCallback(() => { // 先将当前阶段标记为不可执行 setIsReady(false); // 延迟切换到下一个阶段 setTimeout(() => { switch (currentStage) { case 'input': setCurrentStage('wave'); break; case 'wave': setCurrentStage('final'); break; case 'final': setAnimationCycle(prev => prev + 1); setCurrentStage('input'); break; } // 给下一个阶段一些准备时间 setTimeout(() => { setIsReady(true); }, 100); }, 300); }, [currentStage]); return (
); };