forked from 77media/video-flow
3-调整动画
This commit is contained in:
parent
8d85eee872
commit
39c5e99c88
@ -58,7 +58,7 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.videoContainer-qteKNi {
|
.videoContainer-qteKNi {
|
||||||
flex: 3;
|
/* flex: 3; */
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
display: flex
|
display: flex
|
||||||
;
|
;
|
||||||
|
|||||||
@ -524,46 +524,114 @@ export default function WorkFlow() {
|
|||||||
}, [isLoading, currentStep, isGeneratingSketch, sketchCount, isGeneratingVideo, taskVideos.length, taskSketch.length]);
|
}, [isLoading, currentStep, isGeneratingSketch, sketchCount, isGeneratingVideo, taskVideos.length, taskSketch.length]);
|
||||||
|
|
||||||
const renderSketchContent = () => {
|
const renderSketchContent = () => {
|
||||||
if (!taskObject) {
|
|
||||||
|
// 展示最终成片
|
||||||
|
if (Number(currentStep) === 6) {
|
||||||
return (
|
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">
|
<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
|
<motion.div
|
||||||
className="flex flex-col items-center gap-4"
|
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" }}
|
||||||
|
>
|
||||||
|
<video
|
||||||
|
className="w-full h-full rounded-lg object-cover object-center"
|
||||||
|
src={taskVideos[currentSketchIndex]?.url}
|
||||||
|
autoPlay
|
||||||
|
loop
|
||||||
|
muted
|
||||||
|
playsInline
|
||||||
|
/>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
{/* 最终成片视频 */}
|
||||||
|
<motion.div
|
||||||
|
initial={{ clipPath: "inset(0 50% 0 50%)", filter: "blur(10px)" }}
|
||||||
|
animate={{ clipPath: "inset(0 0% 0 0%)", filter: "blur(0px)" }}
|
||||||
|
transition={{
|
||||||
|
clipPath: { duration: 1.2, ease: [0.43, 0.13, 0.23, 0.96] },
|
||||||
|
filter: { duration: 0.6, delay: 0.3 }
|
||||||
|
}}
|
||||||
|
className="relative z-10"
|
||||||
|
>
|
||||||
|
<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 }}
|
initial={{ opacity: 0, y: 20 }}
|
||||||
animate={{ opacity: 1, y: 0 }}
|
animate={{ opacity: 1, y: 0 }}
|
||||||
transition={{ duration: 0.5 }}
|
transition={{ delay: 1, duration: 0.6 }}
|
||||||
>
|
>
|
||||||
|
<div className="flex items-center justify-between">
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
<motion.div
|
<motion.div
|
||||||
|
className="w-2 h-2 rounded-full bg-emerald-500"
|
||||||
animate={{
|
animate={{
|
||||||
scale: [1, 1.2, 1],
|
scale: [1, 1.2, 1],
|
||||||
rotate: [0, 360],
|
opacity: [1, 0.6, 1]
|
||||||
}}
|
}}
|
||||||
transition={{
|
transition={{
|
||||||
duration: 2,
|
duration: 2,
|
||||||
repeat: Infinity,
|
repeat: Infinity,
|
||||||
ease: "linear"
|
ease: "easeInOut"
|
||||||
}}
|
}}
|
||||||
>
|
/>
|
||||||
<Loader2 className="w-8 h-8 text-blue-500" />
|
<span className="text-sm font-medium text-white/90">最终成片</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
<motion.p
|
|
||||||
className="text-sm text-white/70"
|
{/* 完成标记 */}
|
||||||
animate={{
|
<motion.div
|
||||||
opacity: [0.5, 1, 0.5],
|
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"
|
||||||
transition={{
|
initial={{ opacity: 0, scale: 0.8, x: 20 }}
|
||||||
duration: 2,
|
animate={{ opacity: 1, scale: 1, x: 0 }}
|
||||||
repeat: Infinity,
|
transition={{ delay: 1.2, duration: 0.6 }}
|
||||||
ease: "linear"
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
加载中...
|
制作完成
|
||||||
</motion.p>
|
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 展示分镜视频
|
||||||
if (Number(currentStep) > 2 && Number(currentStep) < 6) {
|
if (Number(currentStep) > 2 && Number(currentStep) < 6) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@ -574,7 +642,42 @@ export default function WorkFlow() {
|
|||||||
{taskVideos[currentSketchIndex] ? (
|
{taskVideos[currentSketchIndex] ? (
|
||||||
<ProgressiveReveal
|
<ProgressiveReveal
|
||||||
className="w-full h-full rounded-lg"
|
className="w-full h-full rounded-lg"
|
||||||
{...presets.main}
|
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
|
<video
|
||||||
ref={mainVideoRef}
|
ref={mainVideoRef}
|
||||||
@ -592,84 +695,18 @@ export default function WorkFlow() {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
</motion.div>
|
||||||
|
</div>
|
||||||
</ProgressiveReveal>
|
</ProgressiveReveal>
|
||||||
) : (
|
) : (
|
||||||
<div className="w-full h-full flex items-center justify-center rounded-lg overflow-hidden relative">
|
<div className="w-full h-full flex items-center justify-center rounded-lg overflow-hidden relative">
|
||||||
{/* 动态渐变背景 */}
|
{/* 保持显示当前分镜草图 */}
|
||||||
<motion.div
|
<img
|
||||||
className="absolute inset-0 bg-gradient-to-r from-cyan-300 via-sky-400 to-blue-500"
|
className="absolute inset-0 w-full h-full object-cover"
|
||||||
animate={{
|
src={taskSketch[currentSketchIndex]?.url}
|
||||||
backgroundPosition: ["0% 50%", "100% 50%", "0% 50%"],
|
alt={`分镜草图 ${currentSketchIndex + 1}`}
|
||||||
}}
|
|
||||||
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"
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<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>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@ -690,11 +727,6 @@ export default function WorkFlow() {
|
|||||||
tooltip="编辑分镜"
|
tooltip="编辑分镜"
|
||||||
onClick={() => handleEditModalOpen('3')}
|
onClick={() => handleEditModalOpen('3')}
|
||||||
/>
|
/>
|
||||||
{/* <GlassIconButton
|
|
||||||
icon={FileText}
|
|
||||||
tooltip="显示脚本"
|
|
||||||
onClick={() => console.log('显示脚本')}
|
|
||||||
/> */}
|
|
||||||
</motion.div>
|
</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 (
|
return (
|
||||||
<div
|
<div
|
||||||
className="relative w-full h-full rounded-lg"
|
className="relative w-full h-full rounded-lg"
|
||||||
@ -890,31 +828,7 @@ export default function WorkFlow() {
|
|||||||
ease: "linear"
|
ease: "linear"
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<motion.div
|
|
||||||
animate={{
|
|
||||||
rotate: [0, 360],
|
|
||||||
}}
|
|
||||||
transition={{
|
|
||||||
duration: 2,
|
|
||||||
repeat: Infinity,
|
|
||||||
ease: "linear"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
</motion.div>
|
|
||||||
</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>
|
</motion.div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@ -936,11 +850,6 @@ export default function WorkFlow() {
|
|||||||
tooltip="编辑分镜"
|
tooltip="编辑分镜"
|
||||||
onClick={() => handleEditModalOpen('1')}
|
onClick={() => handleEditModalOpen('1')}
|
||||||
/>
|
/>
|
||||||
{/* <GlassIconButton
|
|
||||||
icon={FileText}
|
|
||||||
tooltip="显示脚本"
|
|
||||||
onClick={() => console.log('显示脚本')}
|
|
||||||
/> */}
|
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
@ -969,7 +878,6 @@ export default function WorkFlow() {
|
|||||||
</motion.div>
|
</motion.div>
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
|
|
||||||
|
|
||||||
{/* 播放进度指示器 */}
|
{/* 播放进度指示器 */}
|
||||||
<AnimatePresence>
|
<AnimatePresence>
|
||||||
{isPlaying && (
|
{isPlaying && (
|
||||||
@ -1003,6 +911,60 @@ export default function WorkFlow() {
|
|||||||
<>
|
<>
|
||||||
<div className="title-JtMejk">{taskObject?.projectName}:{taskObject?.taskName}</div>
|
<div className="title-JtMejk">{taskObject?.projectName}:{taskObject?.taskName}</div>
|
||||||
{/* 实时反馈当前 currentLoadingText */}
|
{/* 实时反馈当前 currentLoadingText */}
|
||||||
|
{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
|
<motion.div
|
||||||
className="flex items-center gap-2 justify-center"
|
className="flex items-center gap-2 justify-center"
|
||||||
initial={{ opacity: 0, y: -10 }}
|
initial={{ opacity: 0, y: -10 }}
|
||||||
@ -1058,12 +1020,13 @@ export default function WorkFlow() {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="media-Ocdu1O">
|
<div className="media-Ocdu1O">
|
||||||
<div className="videoContainer-qteKNi" ref={containerRef}>
|
<div className="videoContainer-qteKNi" style={currentStep !== '6' ? { flex: 3 } : {}} ref={containerRef}>
|
||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
<Skeleton className="w-full aspect-video rounded-lg" />
|
<Skeleton className="w-full aspect-video rounded-lg" />
|
||||||
) : (
|
) : (
|
||||||
@ -1091,98 +1054,70 @@ export default function WorkFlow() {
|
|||||||
onMouseUp={handleMouseUp}
|
onMouseUp={handleMouseUp}
|
||||||
onMouseLeave={() => setIsDragging(false)}
|
onMouseLeave={() => setIsDragging(false)}
|
||||||
>
|
>
|
||||||
|
{Number(currentStep) === 6 ? null : (
|
||||||
|
<>
|
||||||
{(Number(currentStep) > 2 && Number(currentStep) < 6) ? (
|
{(Number(currentStep) > 2 && Number(currentStep) < 6) ? (
|
||||||
<>
|
<>
|
||||||
{renderedVideos}
|
{taskSketch.map((sketch, index) => (
|
||||||
{isGeneratingVideo && taskVideos.length < taskSketch.length && (
|
<div
|
||||||
<motion.div
|
key={`video-${index}`}
|
||||||
className="relative aspect-video rounded-lg overflow-hidden"
|
className={`relative aspect-video rounded-lg overflow-hidden
|
||||||
initial={{ opacity: 0, scale: 0.8 }}
|
${currentSketchIndex === index ? 'ring-2 ring-blue-500 z-10' : 'hover:ring-2 hover:ring-blue-500/50'}`}
|
||||||
animate={{ opacity: 1, scale: 1 }}
|
onClick={() => !isDragging && setCurrentSketchIndex(index)}
|
||||||
transition={{ duration: 0.3 }}
|
|
||||||
>
|
>
|
||||||
{/* 动态渐变背景 */}
|
<ProgressiveReveal
|
||||||
<motion.div
|
{...presets.thumbnail}
|
||||||
className="absolute inset-0 bg-gradient-to-r from-cyan-300 via-sky-400 to-blue-500"
|
delay={index * 0.1}
|
||||||
animate={{
|
customVariants={{
|
||||||
backgroundPosition: ["0% 50%", "100% 50%", "0% 50%"],
|
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={{
|
loadingBgConfig={{
|
||||||
duration: 5,
|
...presets.thumbnail.loadingBgConfig,
|
||||||
repeat: Infinity,
|
glowOpacity: 0.4,
|
||||||
ease: "linear"
|
duration: 4
|
||||||
}}
|
|
||||||
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],
|
|
||||||
}}
|
|
||||||
transition={{
|
|
||||||
duration: 4,
|
|
||||||
repeat: Infinity,
|
|
||||||
ease: "linear"
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<motion.div
|
|
||||||
animate={{
|
|
||||||
rotate: [0, 360],
|
|
||||||
}}
|
|
||||||
transition={{
|
|
||||||
duration: 2,
|
|
||||||
repeat: Infinity,
|
|
||||||
ease: "linear"
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
</motion.div>
|
<div className="w-full h-full transform hover:scale-105 transition-transform duration-500">
|
||||||
</div>
|
{taskVideos[index] ? (
|
||||||
</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
|
<video
|
||||||
className="w-full h-full object-cover"
|
className="w-full h-full object-cover"
|
||||||
src={MOCK_FINAL_VIDEO.url}
|
src={taskVideos[index].url}
|
||||||
poster={MOCK_FINAL_VIDEO.thumbnail}
|
|
||||||
muted
|
muted
|
||||||
playsInline
|
playsInline
|
||||||
loop
|
loop
|
||||||
|
poster={sketch.url}
|
||||||
/>
|
/>
|
||||||
<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>
|
<img
|
||||||
|
className="w-full h-full object-cover"
|
||||||
|
src={sketch.url}
|
||||||
|
alt={`缩略图 ${index + 1}`}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</motion.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>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
{renderedSketches}
|
{renderedSketches}
|
||||||
@ -1237,17 +1172,6 @@ export default function WorkFlow() {
|
|||||||
ease: "linear"
|
ease: "linear"
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<motion.div
|
|
||||||
animate={{
|
|
||||||
rotate: [0, 360],
|
|
||||||
}}
|
|
||||||
transition={{
|
|
||||||
duration: 2,
|
|
||||||
repeat: Infinity,
|
|
||||||
ease: "linear"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
</motion.div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="absolute bottom-0 left-0 right-0 p-2 bg-gradient-to-t from-black/60 to-transparent">
|
<div className="absolute bottom-0 left-0 right-0 p-2 bg-gradient-to-t from-black/60 to-transparent">
|
||||||
@ -1257,6 +1181,8 @@ export default function WorkFlow() {
|
|||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user