3-调整动画

This commit is contained in:
北枳 2025-06-29 01:34:20 +08:00
parent 8d85eee872
commit 39c5e99c88
2 changed files with 380 additions and 454 deletions

View File

@ -58,7 +58,7 @@
overflow: hidden;
}
.videoContainer-qteKNi {
flex: 3;
/* flex: 3; */
min-height: 0;
display: flex
;

View File

@ -524,46 +524,114 @@ export default function WorkFlow() {
}, [isLoading, currentStep, isGeneratingSketch, sketchCount, isGeneratingVideo, taskVideos.length, taskSketch.length]);
const renderSketchContent = () => {
if (!taskObject) {
// 展示最终成片
if (Number(currentStep) === 6) {
return (
<div className="w-full h-full flex items-center justify-center bg-gradient-to-br from-black/40 via-black/20 to-black/40 backdrop-blur-sm rounded-lg overflow-hidden">
<motion.div
className="flex flex-col items-center gap-4"
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5 }}
>
<div className="relative w-full h-full rounded-lg overflow-hidden" onMouseEnter={() => setShowControls(true)} onMouseLeave={() => setShowControls(false)}>
<div className="relative w-full h-full">
{/* 背景模糊的视频 */}
<motion.div
animate={{
scale: [1, 1.2, 1],
rotate: [0, 360],
}}
transition={{
duration: 2,
repeat: Infinity,
ease: "linear"
}}
className="absolute inset-0 overflow-hidden"
initial={{ filter: "blur(0px)", scale: 1, opacity: 1 }}
animate={{ filter: "blur(20px)", scale: 1.1, opacity: 0.5 }}
transition={{ duration: 0.8, ease: "easeInOut" }}
>
<Loader2 className="w-8 h-8 text-blue-500" />
<video
className="w-full h-full rounded-lg object-cover object-center"
src={taskVideos[currentSketchIndex]?.url}
autoPlay
loop
muted
playsInline
/>
</motion.div>
<motion.p
className="text-sm text-white/70"
animate={{
opacity: [0.5, 1, 0.5],
}}
{/* 最终成片视频 */}
<motion.div
initial={{ clipPath: "inset(0 50% 0 50%)", filter: "blur(10px)" }}
animate={{ clipPath: "inset(0 0% 0 0%)", filter: "blur(0px)" }}
transition={{
duration: 2,
repeat: Infinity,
ease: "linear"
clipPath: { duration: 1.2, ease: [0.43, 0.13, 0.23, 0.96] },
filter: { duration: 0.6, delay: 0.3 }
}}
className="relative z-10"
>
...
</motion.p>
</motion.div>
<video
className="w-full h-full object-cover rounded-lg"
src={MOCK_FINAL_VIDEO.url}
poster={MOCK_FINAL_VIDEO.thumbnail}
autoPlay
loop
muted
playsInline
/>
</motion.div>
{/* 操作按钮组 */}
<AnimatePresence>
{showControls && (
<>
{/* 顶部按钮组 */}
<motion.div
className="absolute top-4 right-4 z-10 flex gap-2"
initial={{ opacity: 0, y: -10 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -10 }}
transition={{ duration: 0.2 }}
>
<GlassIconButton
icon={Edit3}
tooltip="编辑分镜"
onClick={() => handleEditModalOpen('4')}
/>
</motion.div>
</>
)}
</AnimatePresence>
{/* 视频信息浮层 */}
<motion.div
className="absolute bottom-0 left-0 right-0 z-10 p-4 bg-gradient-to-t from-black/80 via-black/40 to-transparent"
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 1, duration: 0.6 }}
>
<div className="flex items-center justify-between">
<div className="flex items-center gap-3">
<motion.div
className="w-2 h-2 rounded-full bg-emerald-500"
animate={{
scale: [1, 1.2, 1],
opacity: [1, 0.6, 1]
}}
transition={{
duration: 2,
repeat: Infinity,
ease: "easeInOut"
}}
/>
<span className="text-sm font-medium text-white/90"></span>
</div>
</div>
</motion.div>
{/* 完成标记 */}
<motion.div
className="absolute top-4 right-4 px-3 py-1.5 rounded-full bg-emerald-500/20 backdrop-blur-sm
border border-emerald-500/30 text-emerald-400 text-sm font-medium"
initial={{ opacity: 0, scale: 0.8, x: 20 }}
animate={{ opacity: 1, scale: 1, x: 0 }}
transition={{ delay: 1.2, duration: 0.6 }}
>
</motion.div>
</div>
</div>
);
}
// 展示分镜视频
if (Number(currentStep) > 2 && Number(currentStep) < 6) {
return (
<div
@ -574,102 +642,71 @@ export default function WorkFlow() {
{taskVideos[currentSketchIndex] ? (
<ProgressiveReveal
className="w-full h-full rounded-lg"
{...presets.main}
>
<video
ref={mainVideoRef}
key={taskVideos[currentSketchIndex].url}
className="w-full h-full rounded-lg object-cover object-center"
src={taskVideos[currentSketchIndex].url}
autoPlay={isVideoPlaying}
muted
loop={false}
playsInline
poster={taskSketch[currentSketchIndex]?.url}
onEnded={() => {
if (isVideoPlaying) {
setCurrentSketchIndex(prev => (prev + 1) % taskVideos.length);
customVariants={{
hidden: {
opacity: 0,
filter: "blur(20px)",
clipPath: "inset(0 100% 0 0)"
},
visible: {
opacity: 1,
filter: "blur(0px)",
clipPath: "inset(0 0% 0 0)",
transition: {
duration: 1,
ease: [0.43, 0.13, 0.23, 0.96],
opacity: { duration: 0.8, ease: "easeOut" },
filter: { duration: 0.6, ease: "easeOut" },
clipPath: { duration: 0.8, ease: "easeInOut" }
}
}}
/>
}
}}
>
<div className="relative w-full h-full">
{/* 背景模糊的图片 */}
<div className="absolute inset-0 overflow-hidden">
<img
className="w-full h-full object-cover filter blur-lg scale-110 opacity-50"
src={taskSketch[currentSketchIndex]?.url}
alt="background"
/>
</div>
{/* 视频 */}
<motion.div
initial={{ clipPath: "inset(0 100% 0 0)" }}
animate={{ clipPath: "inset(0 0% 0 0)" }}
transition={{ duration: 0.8, ease: [0.43, 0.13, 0.23, 0.96] }}
className="relative z-10"
>
<video
ref={mainVideoRef}
key={taskVideos[currentSketchIndex].url}
className="w-full h-full rounded-lg object-cover object-center"
src={taskVideos[currentSketchIndex].url}
autoPlay={isVideoPlaying}
muted
loop={false}
playsInline
poster={taskSketch[currentSketchIndex]?.url}
onEnded={() => {
if (isVideoPlaying) {
setCurrentSketchIndex(prev => (prev + 1) % taskVideos.length);
}
}}
/>
</motion.div>
</div>
</ProgressiveReveal>
) : (
<div className="w-full h-full flex items-center justify-center rounded-lg overflow-hidden relative">
{/* 动态渐变背景 */}
<motion.div
className="absolute inset-0 bg-gradient-to-r from-cyan-300 via-sky-400 to-blue-500"
animate={{
backgroundPosition: ["0% 50%", "100% 50%", "0% 50%"],
}}
transition={{
duration: 5,
repeat: Infinity,
ease: "linear"
}}
style={{
backgroundSize: "200% 200%",
}}
{/* 保持显示当前分镜草图 */}
<img
className="absolute inset-0 w-full h-full object-cover"
src={taskSketch[currentSketchIndex]?.url}
alt={`分镜草图 ${currentSketchIndex + 1}`}
/>
{/* 动态光效 */}
<motion.div
className="absolute inset-0 opacity-50"
style={{
background: "radial-gradient(circle at center, rgba(255,255,255,0.8) 0%, transparent 50%)",
}}
animate={{
scale: [1, 1.2, 1],
}}
transition={{
duration: 2,
repeat: Infinity,
ease: "easeInOut"
}}
/>
<motion.div
className="flex flex-col items-center gap-4 relative z-10"
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5 }}
>
<div className="relative">
<motion.div
className="absolute -inset-4 bg-gradient-to-r from-white via-sky-200 to-cyan-200 rounded-full opacity-60 blur-xl"
animate={{
scale: [1, 1.2, 1],
rotate: [0, 180, 360],
}}
transition={{
duration: 4,
repeat: Infinity,
ease: "linear"
}}
/>
<motion.div
animate={{
rotate: [0, 360],
}}
transition={{
duration: 2,
repeat: Infinity,
ease: "linear"
}}
>
</motion.div>
</div>
<motion.p
className="text-sm text-white font-medium"
animate={{
opacity: [0.7, 1, 0.7],
}}
transition={{
duration: 2,
repeat: Infinity,
ease: "linear"
}}
>
{taskVideos.length + 1}/{taskSketch.length}
</motion.p>
</motion.div>
</div>
)}
@ -690,11 +727,6 @@ export default function WorkFlow() {
tooltip="编辑分镜"
onClick={() => handleEditModalOpen('3')}
/>
{/* <GlassIconButton
icon={FileText}
tooltip="显示脚本"
onClick={() => console.log('显示脚本')}
/> */}
</motion.div>
</>
)}
@ -726,101 +758,7 @@ export default function WorkFlow() {
);
}
// 展示最终成片
if (Number(currentStep) === 6) {
return (
<div className="relative w-full h-full rounded-lg overflow-hidden">
<ProgressiveReveal
className="w-full h-full rounded-lg"
customVariants={{
hidden: {
opacity: 0,
filter: "blur(20px)",
clipPath: "inset(0 50% 0 50%)"
},
visible: {
opacity: 1,
filter: "blur(0px)",
clipPath: "inset(0 0% 0 0%)",
transition: {
duration: 1.2,
ease: [0.43, 0.13, 0.23, 0.96], // 自定义缓动函数
opacity: { duration: 0.8, ease: "easeOut" },
filter: { duration: 0.6, ease: "easeOut" },
clipPath: { duration: 1, ease: "easeInOut", delay: 0.2 }
}
}
}}
loadingBgConfig={{
fromColor: 'from-emerald-300',
viaColor: 'via-cyan-400',
toColor: 'to-blue-500',
glowOpacity: 0.6,
duration: 6
}}
>
<div className="relative w-full h-full">
{/* 最终成片视频 */}
<video
className="w-full h-full object-cover rounded-lg"
src={MOCK_FINAL_VIDEO.url}
poster={MOCK_FINAL_VIDEO.thumbnail}
autoPlay
loop
muted
playsInline
/>
{/* 视频信息浮层 */}
<motion.div
className="absolute bottom-0 left-0 right-0 p-4 bg-gradient-to-t from-black/80 via-black/40 to-transparent"
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 1, duration: 0.6 }}
>
<div className="flex items-center justify-between">
<div className="flex items-center gap-3">
<motion.div
className="w-2 h-2 rounded-full bg-emerald-500"
animate={{
scale: [1, 1.2, 1],
opacity: [1, 0.6, 1]
}}
transition={{
duration: 2,
repeat: Infinity,
ease: "easeInOut"
}}
/>
<span className="text-sm font-medium text-white/90"></span>
</div>
<div className="flex items-center gap-2">
<GlassIconButton
icon={Edit3}
tooltip="编辑成片"
onClick={() => handleEditModalOpen('4')}
size="sm"
/>
</div>
</div>
</motion.div>
{/* 完成标记 */}
<motion.div
className="absolute top-4 right-4 px-3 py-1.5 rounded-full bg-emerald-500/20 backdrop-blur-sm
border border-emerald-500/30 text-emerald-400 text-sm font-medium"
initial={{ opacity: 0, scale: 0.8, x: 20 }}
animate={{ opacity: 1, scale: 1, x: 0 }}
transition={{ delay: 1.2, duration: 0.6 }}
>
</motion.div>
</div>
</ProgressiveReveal>
</div>
);
}
// 展示分镜草图
return (
<div
className="relative w-full h-full rounded-lg"
@ -890,31 +828,7 @@ export default function WorkFlow() {
ease: "linear"
}}
/>
<motion.div
animate={{
rotate: [0, 360],
}}
transition={{
duration: 2,
repeat: Infinity,
ease: "linear"
}}
>
</motion.div>
</div>
<motion.p
className="text-sm text-white font-medium"
animate={{
opacity: [0.7, 1, 0.7],
}}
transition={{
duration: 2,
repeat: Infinity,
ease: "linear"
}}
>
{sketchCount + 1}/{MOCK_SKETCH_COUNT}
</motion.p>
</motion.div>
</div>
)}
@ -936,11 +850,6 @@ export default function WorkFlow() {
tooltip="编辑分镜"
onClick={() => handleEditModalOpen('1')}
/>
{/* <GlassIconButton
icon={FileText}
tooltip="显示脚本"
onClick={() => console.log('显示脚本')}
/> */}
</motion.div>
</>
)}
@ -968,7 +877,6 @@ export default function WorkFlow() {
</motion.div>
</motion.div>
</AnimatePresence>
{/* 播放进度指示器 */}
<AnimatePresence>
@ -1003,67 +911,122 @@ export default function WorkFlow() {
<>
<div className="title-JtMejk">{taskObject?.projectName}{taskObject?.taskName}</div>
{/* 实时反馈当前 currentLoadingText */}
<motion.div
className="flex items-center gap-2 justify-center"
initial={{ opacity: 0, y: -10 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.3 }}
>
<motion.div
className="w-1.5 h-1.5 rounded-full bg-blue-500"
animate={{
scale: [1, 1.5, 1],
opacity: [1, 0.5, 1]
}}
transition={{
duration: 1,
repeat: Infinity,
repeatDelay: 0.2
}}
/>
<motion.p
className="normalS400 subtitle-had8uE text-blue-500/80"
key={currentLoadingText}
initial={{ opacity: 0, x: -10 }}
animate={{ opacity: 1, x: 0 }}
exit={{ opacity: 0, x: 10 }}
{currentLoadingText === '任务完成' ? (
<motion.div
className="flex items-center gap-3 justify-center"
initial={{ opacity: 0, y: -10 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5 }}
>
<motion.div
className="w-2 h-2 rounded-full bg-emerald-500"
animate={{
scale: [1, 1.5, 1],
opacity: [1, 0.5, 1]
}}
transition={{
duration: 1,
repeat: Infinity,
repeatDelay: 0.2
}}
/>
<motion.div
className="flex items-center gap-1.5"
initial="hidden"
animate="visible"
variants={{
hidden: { opacity: 0 },
visible: { opacity: 1 }
}}
>
<motion.span
className="text-emerald-500 font-medium"
variants={{
hidden: { opacity: 0, y: 20 },
visible: { opacity: 1, y: 0 }
}}
transition={{ duration: 0.5 }}
>
{currentLoadingText}
</motion.span>
</motion.div>
<motion.div
className="w-2 h-2 rounded-full bg-emerald-500"
animate={{
scale: [1, 1.5, 1],
opacity: [1, 0.5, 1]
}}
transition={{
duration: 1,
repeat: Infinity,
repeatDelay: 0.2,
delay: 0.3
}}
/>
</motion.div>
) : (
<motion.div
className="flex items-center gap-2 justify-center"
initial={{ opacity: 0, y: -10 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.3 }}
>
{currentLoadingText}
</motion.p>
<motion.div
className="w-1.5 h-1.5 rounded-full bg-blue-500"
animate={{
scale: [1, 1.5, 1],
opacity: [1, 0.5, 1]
}}
transition={{
duration: 1,
repeat: Infinity,
repeatDelay: 0.2,
delay: 0.3
}}
/>
<motion.div
className="w-1.5 h-1.5 rounded-full bg-blue-500"
animate={{
scale: [1, 1.5, 1],
opacity: [1, 0.5, 1]
}}
transition={{
duration: 1,
repeat: Infinity,
repeatDelay: 0.2,
delay: 0.6
}}
/>
</motion.div>
<motion.div
className="w-1.5 h-1.5 rounded-full bg-blue-500"
animate={{
scale: [1, 1.5, 1],
opacity: [1, 0.5, 1]
}}
transition={{
duration: 1,
repeat: Infinity,
repeatDelay: 0.2
}}
/>
<motion.p
className="normalS400 subtitle-had8uE text-blue-500/80"
key={currentLoadingText}
initial={{ opacity: 0, x: -10 }}
animate={{ opacity: 1, x: 0 }}
exit={{ opacity: 0, x: 10 }}
transition={{ duration: 0.3 }}
>
{currentLoadingText}
</motion.p>
<motion.div
className="w-1.5 h-1.5 rounded-full bg-blue-500"
animate={{
scale: [1, 1.5, 1],
opacity: [1, 0.5, 1]
}}
transition={{
duration: 1,
repeat: Infinity,
repeatDelay: 0.2,
delay: 0.3
}}
/>
<motion.div
className="w-1.5 h-1.5 rounded-full bg-blue-500"
animate={{
scale: [1, 1.5, 1],
opacity: [1, 0.5, 1]
}}
transition={{
duration: 1,
repeat: Infinity,
repeatDelay: 0.2,
delay: 0.6
}}
/>
</motion.div>
)}
</>
)}
</div>
</div>
<div className="media-Ocdu1O">
<div className="videoContainer-qteKNi" ref={containerRef}>
<div className="videoContainer-qteKNi" style={currentStep !== '6' ? { flex: 3 } : {}} ref={containerRef}>
{isLoading ? (
<Skeleton className="w-full aspect-video rounded-lg" />
) : (
@ -1091,169 +1054,132 @@ export default function WorkFlow() {
onMouseUp={handleMouseUp}
onMouseLeave={() => setIsDragging(false)}
>
{(Number(currentStep) > 2 && Number(currentStep) < 6) ? (
{Number(currentStep) === 6 ? null : (
<>
{renderedVideos}
{isGeneratingVideo && taskVideos.length < taskSketch.length && (
<motion.div
className="relative aspect-video rounded-lg overflow-hidden"
initial={{ opacity: 0, scale: 0.8 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ duration: 0.3 }}
>
{/* 动态渐变背景 */}
<motion.div
className="absolute inset-0 bg-gradient-to-r from-cyan-300 via-sky-400 to-blue-500"
animate={{
backgroundPosition: ["0% 50%", "100% 50%", "0% 50%"],
}}
transition={{
duration: 5,
repeat: Infinity,
ease: "linear"
}}
style={{
backgroundSize: "200% 200%",
}}
/>
{/* 动态光效 */}
<motion.div
className="absolute inset-0 opacity-50"
style={{
background: "radial-gradient(circle at center, rgba(255,255,255,0.8) 0%, transparent 50%)",
}}
animate={{
scale: [1, 1.2, 1],
}}
transition={{
duration: 2,
repeat: Infinity,
ease: "easeInOut"
}}
/>
<div className="absolute inset-0 flex items-center justify-center">
<div className="relative">
<motion.div
className="absolute -inset-4 bg-gradient-to-r from-white via-sky-200 to-cyan-200 rounded-full opacity-60 blur-xl"
animate={{
scale: [1, 1.2, 1],
rotate: [0, 180, 360],
{(Number(currentStep) > 2 && Number(currentStep) < 6) ? (
<>
{taskSketch.map((sketch, index) => (
<div
key={`video-${index}`}
className={`relative aspect-video rounded-lg overflow-hidden
${currentSketchIndex === index ? 'ring-2 ring-blue-500 z-10' : 'hover:ring-2 hover:ring-blue-500/50'}`}
onClick={() => !isDragging && setCurrentSketchIndex(index)}
>
<ProgressiveReveal
{...presets.thumbnail}
delay={index * 0.1}
customVariants={{
hidden: {
opacity: 0,
scale: 0.95,
filter: "blur(10px)"
},
visible: {
opacity: 1,
scale: 1,
filter: "blur(0px)",
transition: {
duration: 0.8,
ease: [0.23, 1, 0.32, 1],
opacity: { duration: 0.6, ease: "easeInOut" },
scale: { duration: 1, ease: "easeOut" },
filter: { duration: 0.8, ease: "easeOut", delay: 0.2 }
}
}
}}
transition={{
duration: 4,
repeat: Infinity,
ease: "linear"
}}
/>
<motion.div
animate={{
rotate: [0, 360],
}}
transition={{
duration: 2,
repeat: Infinity,
ease: "linear"
loadingBgConfig={{
...presets.thumbnail.loadingBgConfig,
glowOpacity: 0.4,
duration: 4
}}
>
</motion.div>
<div className="w-full h-full transform hover:scale-105 transition-transform duration-500">
{taskVideos[index] ? (
<video
className="w-full h-full object-cover"
src={taskVideos[index].url}
muted
playsInline
loop
poster={sketch.url}
/>
) : (
<img
className="w-full h-full object-cover"
src={sketch.url}
alt={`缩略图 ${index + 1}`}
/>
)}
</div>
</ProgressiveReveal>
<div className="absolute bottom-0 left-0 right-0 p-2 bg-gradient-to-t from-black/60 to-transparent">
<span className="text-xs text-white/90"> {index + 1}</span>
</div>
</div>
</div>
<div className="absolute bottom-0 left-0 right-0 p-2 bg-gradient-to-t from-black/60 to-transparent">
<span className="text-xs text-white/90"> {taskVideos.length + 1}</span>
</div>
</motion.div>
)}
</>
) : Number(currentStep) === 6 ? (
<motion.div
className="relative aspect-video rounded-lg overflow-hidden"
initial={{ opacity: 0, scale: 0.9 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ duration: 0.6, delay: 1.4 }}
>
<video
className="w-full h-full object-cover"
src={MOCK_FINAL_VIDEO.url}
poster={MOCK_FINAL_VIDEO.thumbnail}
muted
playsInline
loop
/>
<div className="absolute inset-0 flex items-center justify-center bg-black/40 backdrop-blur-sm">
<span className="text-sm font-medium text-white"></span>
</div>
</motion.div>
) : (
<>
{renderedSketches}
{isGeneratingSketch && sketchCount < MOCK_SKETCH_COUNT && (
<motion.div
className="relative aspect-video rounded-lg overflow-hidden"
initial={{ opacity: 0, scale: 0.8 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ duration: 0.3 }}
>
{/* 动态渐变背景 */}
<motion.div
className="absolute inset-0 bg-gradient-to-r from-cyan-300 via-sky-400 to-blue-500"
animate={{
backgroundPosition: ["0% 50%", "100% 50%", "0% 50%"],
}}
transition={{
duration: 5,
repeat: Infinity,
ease: "linear"
}}
style={{
backgroundSize: "200% 200%",
}}
/>
{/* 动态光效 */}
<motion.div
className="absolute inset-0 opacity-50"
style={{
background: "radial-gradient(circle at center, rgba(255,255,255,0.8) 0%, transparent 50%)",
}}
animate={{
scale: [1, 1.2, 1],
}}
transition={{
duration: 2,
repeat: Infinity,
ease: "easeInOut"
}}
/>
<div className="absolute inset-0 flex items-center justify-center">
<div className="relative">
<motion.div
className="absolute -inset-4 bg-gradient-to-r from-white via-sky-200 to-cyan-200 rounded-full opacity-60 blur-xl"
animate={{
scale: [1, 1.2, 1],
rotate: [0, 180, 360],
))}
</>
) : (
<>
{renderedSketches}
{isGeneratingSketch && sketchCount < MOCK_SKETCH_COUNT && (
<motion.div
className="relative aspect-video rounded-lg overflow-hidden"
initial={{ opacity: 0, scale: 0.8 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ duration: 0.3 }}
>
{/* 动态渐变背景 */}
<motion.div
className="absolute inset-0 bg-gradient-to-r from-cyan-300 via-sky-400 to-blue-500"
animate={{
backgroundPosition: ["0% 50%", "100% 50%", "0% 50%"],
}}
transition={{
duration: 4,
transition={{
duration: 5,
repeat: Infinity,
ease: "linear"
}}
style={{
backgroundSize: "200% 200%",
}}
/>
<motion.div
animate={{
rotate: [0, 360],
{/* 动态光效 */}
<motion.div
className="absolute inset-0 opacity-50"
style={{
background: "radial-gradient(circle at center, rgba(255,255,255,0.8) 0%, transparent 50%)",
}}
transition={{
animate={{
scale: [1, 1.2, 1],
}}
transition={{
duration: 2,
repeat: Infinity,
ease: "linear"
ease: "easeInOut"
}}
>
</motion.div>
</div>
</div>
<div className="absolute bottom-0 left-0 right-0 p-2 bg-gradient-to-t from-black/60 to-transparent">
<span className="text-xs text-white/90"> {sketchCount + 1}</span>
</div>
</motion.div>
/>
<div className="absolute inset-0 flex items-center justify-center">
<div className="relative">
<motion.div
className="absolute -inset-4 bg-gradient-to-r from-white via-sky-200 to-cyan-200 rounded-full opacity-60 blur-xl"
animate={{
scale: [1, 1.2, 1],
rotate: [0, 180, 360],
}}
transition={{
duration: 4,
repeat: Infinity,
ease: "linear"
}}
/>
</div>
</div>
<div className="absolute bottom-0 left-0 right-0 p-2 bg-gradient-to-t from-black/60 to-transparent">
<span className="text-xs text-white/90"> {sketchCount + 1}</span>
</div>
</motion.div>
)}
</>
)}
</>
)}