import React, { useEffect, useState, useRef } from 'react'; import { Play, Pause, Download, RefreshCw, Film, FileImage, FileArchive } from 'lucide-react'; import { downloadApng, downloadGif, downloadZip } from '../utils/imageUtils'; interface AnimationPreviewProps { frames: string[]; fps: number; isLoading: boolean; } export const AnimationPreview: React.FC = ({ frames, fps, isLoading }) => { const [currentFrameIndex, setCurrentFrameIndex] = useState(0); const [isPlaying, setIsPlaying] = useState(true); const [isDownloading, setIsDownloading] = useState(false); const timerRef = useRef(null); useEffect(() => { if (frames.length === 0 || !isPlaying) { if (timerRef.current) window.clearInterval(timerRef.current); return; } const interval = 1000 / fps; timerRef.current = window.setInterval(() => { setCurrentFrameIndex((prev) => (prev + 1) % frames.length); }, interval); return () => { if (timerRef.current) window.clearInterval(timerRef.current); }; }, [frames, fps, isPlaying]); const handleDownload = async (type: 'APNG' | 'GIF' | 'ZIP') => { if (frames.length === 0) return; setIsDownloading(true); try { const timestamp = new Date().getTime(); const filename = `toonmotion_${timestamp}`; if (type === 'APNG') { await downloadApng(frames, fps, filename); } else if (type === 'GIF') { await downloadGif(frames, fps, filename); } else if (type === 'ZIP') { await downloadZip(frames, filename); } } catch (e) { console.error(e); alert("下载失败,请重试"); } finally { setIsDownloading(false); } }; if (isLoading) { return (

AI 正在绘制每一帧...

Gemini 2.5 正在进行像素级生成

); } if (frames.length === 0) { return (

动画预览区域

生成的动画将显示在这里

); } return (

动画预览

{frames.length} 帧
{/* Canvas Area */}
{`Frame
{/* Control Bar */}
播放进度
{currentFrameIndex + 1}/{frames.length}
{/* Footer Actions - Download Buttons */}
); };