auto-save 2026-05-14 02:52 (~4)
This commit is contained in:
@@ -104,6 +104,8 @@ function clamp(value: number, min: number, max: number) {
|
||||
return Math.max(min, Math.min(max, value))
|
||||
}
|
||||
|
||||
const THUMBNAIL_HEIGHT = 176
|
||||
|
||||
function canvasThumbnailAnchor(root: HTMLDivElement | null, target: HTMLElement) {
|
||||
if (!root) return { x: 160, y: 0 }
|
||||
const rootRect = root.getBoundingClientRect()
|
||||
@@ -356,7 +358,7 @@ export function InputNode({ data, selected }: NodeProps<{ data: NodeData }> | an
|
||||
onClick={(e) => { e.stopPropagation(); fileRef.current?.click() }}
|
||||
title="再上传一个视频"
|
||||
className="shrink-0 rounded-md border border-dashed border-white/30 hover:border-white/50 bg-white/[0.04] hover:bg-white/[0.08] inline-flex items-center justify-center text-white/60 hover:text-white transition"
|
||||
style={{ width: 88, height: 160 }}
|
||||
style={{ width: 96, height: THUMBNAIL_HEIGHT }}
|
||||
>
|
||||
<Plus className="h-4 w-4" />
|
||||
</button>
|
||||
@@ -370,7 +372,7 @@ export function InputNode({ data, selected }: NodeProps<{ data: NodeData }> | an
|
||||
className={`group relative shrink-0 rounded-md overflow-visible border shadow-lg transition hover:-translate-y-0.5 ${
|
||||
isActive ? "border-violet-400 ring-2 ring-violet-400/60" : "border-white/25"
|
||||
}`}
|
||||
style={{ height: 160, aspectRatio: aspectStr }}
|
||||
style={{ height: THUMBNAIL_HEIGHT, aspectRatio: aspectStr }}
|
||||
onMouseEnter={(e) => setHoverPreviewJob({ id: j.id, ...canvasThumbnailAnchor(rootRef.current, e.currentTarget) })}
|
||||
onMouseLeave={() => setHoverPreviewJob(null)}
|
||||
>
|
||||
@@ -765,7 +767,7 @@ export function VisualLabNode({ data, selected }: any) {
|
||||
? isSelected ? "border-emerald-400 ring-2 ring-emerald-400/60" : "border-white/30 dark:border-white/20"
|
||||
: p.borderClass
|
||||
} ${p.kind === "cutout" ? "bg-white" : "bg-black"}`}
|
||||
style={{ height: 150, aspectRatio: aspect }}
|
||||
style={{ height: THUMBNAIL_HEIGHT, aspectRatio: aspect }}
|
||||
onMouseEnter={(e) => setHoverPreview({ id: p.id, ...canvasThumbnailAnchor(rootRef.current, e.currentTarget) })}
|
||||
onMouseLeave={() => setHoverPreview(null)}
|
||||
>
|
||||
@@ -819,9 +821,9 @@ export function VisualLabNode({ data, selected }: any) {
|
||||
d.onCopyImage?.({ kind: "keyframe", frame_idx: p.frameIdx, label: `${p.label} 关键帧` })
|
||||
}}
|
||||
title="复制此图(到分镜头编排工作台插槽粘贴)"
|
||||
className="absolute top-1 left-1 z-[70] h-5 w-5 rounded-full bg-violet-500/90 text-white shadow-md backdrop-blur inline-flex items-center justify-center text-[10px] leading-none transition hover:bg-violet-400 hover:scale-110"
|
||||
className="absolute top-1.5 left-1.5 z-[70] inline-flex h-7 w-7 items-center justify-center rounded-full bg-violet-500/95 text-white shadow-lg backdrop-blur transition hover:scale-110 hover:bg-violet-400"
|
||||
>
|
||||
📋
|
||||
<Copy className="h-3.5 w-3.5" />
|
||||
</button>
|
||||
)}
|
||||
|
||||
@@ -839,9 +841,9 @@ export function VisualLabNode({ data, selected }: any) {
|
||||
})
|
||||
}}
|
||||
title="复制此图(到分镜头编排工作台插槽粘贴)"
|
||||
className="absolute top-1 left-1 z-[70] h-5 w-5 rounded-full bg-violet-500/90 text-white shadow-md backdrop-blur inline-flex items-center justify-center text-[10px] leading-none transition hover:bg-violet-400 hover:scale-110"
|
||||
className="absolute top-1.5 left-1.5 z-[70] inline-flex h-7 w-7 items-center justify-center rounded-full bg-violet-500/95 text-white shadow-lg backdrop-blur transition hover:scale-110 hover:bg-violet-400"
|
||||
>
|
||||
📋
|
||||
<Copy className="h-3.5 w-3.5" />
|
||||
</button>
|
||||
)}
|
||||
|
||||
@@ -855,10 +857,10 @@ export function VisualLabNode({ data, selected }: any) {
|
||||
void navigator.clipboard?.writeText(video.prompt).catch(() => {})
|
||||
toast.success("已复制视频 prompt")
|
||||
}}
|
||||
className="absolute left-1 top-1 z-[70] h-5 w-5 rounded-full bg-violet-500/90 text-white shadow-md backdrop-blur inline-flex items-center justify-center transition hover:bg-violet-400 hover:scale-110"
|
||||
className="absolute left-1.5 top-1.5 z-[70] inline-flex h-7 w-7 items-center justify-center rounded-full bg-violet-500/95 text-white shadow-lg backdrop-blur transition hover:scale-110 hover:bg-violet-400"
|
||||
title="复制视频 prompt"
|
||||
>
|
||||
<Copy className="h-2.5 w-2.5" />
|
||||
<Copy className="h-3.5 w-3.5" />
|
||||
</button>
|
||||
)}
|
||||
|
||||
@@ -870,9 +872,9 @@ export function VisualLabNode({ data, selected }: any) {
|
||||
if (confirm(`删除${p.label}?相关清洗 / 抠图 / 生成图都会一并清除。`)) d.onDeleteFrame?.(p.frameIdx)
|
||||
}}
|
||||
title="删除该关键帧"
|
||||
className="absolute top-1 right-1 z-[70] h-5 w-5 rounded-full bg-black/70 text-white/80 backdrop-blur inline-flex items-center justify-center opacity-0 transition hover:bg-rose-500 hover:text-white group-hover:opacity-100"
|
||||
className="absolute top-1.5 right-1.5 z-[70] inline-flex h-7 w-7 items-center justify-center rounded-full bg-rose-500/95 text-white shadow-lg backdrop-blur transition hover:scale-110 hover:bg-rose-400"
|
||||
>
|
||||
<X className="h-3 w-3" />
|
||||
<Trash2 className="h-3.5 w-3.5" />
|
||||
</button>
|
||||
)}
|
||||
|
||||
@@ -886,9 +888,9 @@ export function VisualLabNode({ data, selected }: any) {
|
||||
}
|
||||
}}
|
||||
title="删除该提取图"
|
||||
className="absolute top-1 right-1 z-[70] h-5 w-5 rounded-full bg-black/70 text-white/85 backdrop-blur inline-flex items-center justify-center opacity-0 transition hover:bg-rose-500 hover:text-white group-hover:opacity-100"
|
||||
className="absolute top-1.5 right-1.5 z-[70] inline-flex h-7 w-7 items-center justify-center rounded-full bg-rose-500/95 text-white shadow-lg backdrop-blur transition hover:scale-110 hover:bg-rose-400"
|
||||
>
|
||||
<X className="h-3 w-3" />
|
||||
<Trash2 className="h-3.5 w-3.5" />
|
||||
</button>
|
||||
)}
|
||||
|
||||
@@ -899,10 +901,10 @@ export function VisualLabNode({ data, selected }: any) {
|
||||
e.stopPropagation()
|
||||
d.onDeleteVideo?.(p.videoId)
|
||||
}}
|
||||
className="absolute right-1 top-1 z-[70] h-5 w-5 rounded-full bg-rose-500/90 text-white shadow-md backdrop-blur inline-flex items-center justify-center transition hover:bg-rose-400 hover:scale-110"
|
||||
className="absolute right-1.5 top-1.5 z-[70] inline-flex h-7 w-7 items-center justify-center rounded-full bg-rose-500/95 text-white shadow-lg backdrop-blur transition hover:scale-110 hover:bg-rose-400"
|
||||
title="删除这个视频任务"
|
||||
>
|
||||
<Trash2 className="h-2.5 w-2.5" />
|
||||
<Trash2 className="h-3.5 w-3.5" />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
@@ -1022,7 +1024,7 @@ export function KeyframeNode({ data, selected }: any) {
|
||||
: "border-white/30 dark:border-white/20"
|
||||
}`}
|
||||
style={{
|
||||
height: 160,
|
||||
height: THUMBNAIL_HEIGHT,
|
||||
aspectRatio: d.job && d.job.height > 0
|
||||
? `${d.job.width}/${d.job.height}`
|
||||
: "16/9",
|
||||
@@ -1078,13 +1080,13 @@ export function KeyframeNode({ data, selected }: any) {
|
||||
label: `分镜 ${f.index + 1} 关键帧`,
|
||||
})
|
||||
}}
|
||||
title="📋 复制此图(到分镜头编排工作台插槽粘贴)"
|
||||
className="absolute top-1 left-1 h-5 w-5 rounded-full bg-violet-500/90 backdrop-blur text-white shadow-md hover:bg-violet-400 hover:scale-110 inline-flex items-center justify-center transition z-[70] text-[10px] leading-none"
|
||||
title="复制此图(到分镜头编排工作台插槽粘贴)"
|
||||
className="absolute top-1.5 left-1.5 z-[70] inline-flex h-7 w-7 items-center justify-center rounded-full bg-violet-500/95 text-white shadow-lg backdrop-blur transition hover:scale-110 hover:bg-violet-400"
|
||||
>
|
||||
📋
|
||||
<Copy className="h-3.5 w-3.5" />
|
||||
</button>
|
||||
)}
|
||||
{/* 删除按钮:hover 时右上角浮出 */}
|
||||
{/* 删除按钮:常驻可见 */}
|
||||
{d.onDeleteFrame && (
|
||||
<button
|
||||
onClick={(e) => {
|
||||
@@ -1094,9 +1096,9 @@ export function KeyframeNode({ data, selected }: any) {
|
||||
}
|
||||
}}
|
||||
title="删除该关键帧"
|
||||
className="absolute top-1 right-1 h-5 w-5 rounded-full bg-black/70 backdrop-blur text-white/80 hover:bg-rose-500 hover:text-white inline-flex items-center justify-center opacity-0 group-hover:opacity-100 transition z-[70]"
|
||||
className="absolute top-1.5 right-1.5 z-[70] inline-flex h-7 w-7 items-center justify-center rounded-full bg-rose-500/95 text-white shadow-lg backdrop-blur transition hover:scale-110 hover:bg-rose-400"
|
||||
>
|
||||
<X className="h-3 w-3" />
|
||||
<Trash2 className="h-3.5 w-3.5" />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
@@ -1544,7 +1546,7 @@ export function StoryboardNode({ data, selected }: any) {
|
||||
<div
|
||||
key={key}
|
||||
className="group relative shrink-0 rounded-md border border-violet-300/50 overflow-visible transition shadow-lg hover:-translate-y-0.5 bg-white"
|
||||
style={{ height: 160, aspectRatio: aspect }}
|
||||
style={{ height: THUMBNAIL_HEIGHT, aspectRatio: aspect }}
|
||||
onMouseEnter={(e) => setHoverPreviewCutout({ id: key, ...canvasThumbnailAnchor(rootRef.current, e.currentTarget) })}
|
||||
onMouseLeave={() => setHoverPreviewCutout(null)}
|
||||
>
|
||||
@@ -1579,13 +1581,13 @@ export function StoryboardNode({ data, selected }: any) {
|
||||
label: p.name,
|
||||
})
|
||||
}}
|
||||
title="📋 复制此图(到分镜头编排工作台插槽粘贴)"
|
||||
className="absolute top-1 left-1 h-5 w-5 rounded-full bg-violet-500/90 backdrop-blur text-white shadow-md hover:bg-violet-400 hover:scale-110 inline-flex items-center justify-center transition z-[70] text-[10px] leading-none"
|
||||
title="复制此图(到分镜头编排工作台插槽粘贴)"
|
||||
className="absolute top-1.5 left-1.5 z-[70] inline-flex h-7 w-7 items-center justify-center rounded-full bg-violet-500/95 text-white shadow-lg backdrop-blur transition hover:scale-110 hover:bg-violet-400"
|
||||
>
|
||||
📋
|
||||
<Copy className="h-3.5 w-3.5" />
|
||||
</button>
|
||||
)}
|
||||
{/* 右上:删除(hover 浮出) */}
|
||||
{/* 右上:删除 */}
|
||||
{d.onDeleteCutout && (
|
||||
<button
|
||||
onClick={(e) => {
|
||||
@@ -1595,9 +1597,9 @@ export function StoryboardNode({ data, selected }: any) {
|
||||
}
|
||||
}}
|
||||
title="删除该提取图"
|
||||
className="absolute top-1 right-1 h-5 w-5 rounded-full bg-black/70 backdrop-blur text-white/85 hover:bg-rose-500 hover:text-white inline-flex items-center justify-center opacity-0 group-hover:opacity-100 transition z-[70]"
|
||||
className="absolute top-1.5 right-1.5 z-[70] inline-flex h-7 w-7 items-center justify-center rounded-full bg-rose-500/95 text-white shadow-lg backdrop-blur transition hover:scale-110 hover:bg-rose-400"
|
||||
>
|
||||
<X className="h-3 w-3" />
|
||||
<Trash2 className="h-3.5 w-3.5" />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
@@ -1695,7 +1697,7 @@ export function VideoGenNode({ data, selected }: any) {
|
||||
className={`group relative shrink-0 rounded-md border overflow-visible transition shadow-lg hover:-translate-y-0.5 bg-black ${
|
||||
ready ? "border-emerald-300/60" : v.status === "failed" ? "border-rose-300/70" : "border-violet-300/55"
|
||||
}`}
|
||||
style={{ height: 160, aspectRatio: aspect }}
|
||||
style={{ height: THUMBNAIL_HEIGHT, aspectRatio: aspect }}
|
||||
onMouseEnter={(e) => setHoverPreviewVideo({ id: v.id, ...canvasThumbnailAnchor(rootRef.current, e.currentTarget) })}
|
||||
onMouseLeave={() => setHoverPreviewVideo(null)}
|
||||
>
|
||||
@@ -1747,10 +1749,10 @@ export function VideoGenNode({ data, selected }: any) {
|
||||
void navigator.clipboard?.writeText(v.prompt).catch(() => {})
|
||||
toast.success("已复制视频 prompt")
|
||||
}}
|
||||
className="absolute left-1 top-1 z-[70] h-5 w-5 rounded-full bg-violet-500/90 text-white shadow-md backdrop-blur inline-flex items-center justify-center transition hover:bg-violet-400 hover:scale-110"
|
||||
className="absolute left-1.5 top-1.5 z-[70] inline-flex h-7 w-7 items-center justify-center rounded-full bg-violet-500/95 text-white shadow-lg backdrop-blur transition hover:scale-110 hover:bg-violet-400"
|
||||
title="复制视频 prompt"
|
||||
>
|
||||
<Copy className="h-2.5 w-2.5" />
|
||||
<Copy className="h-3.5 w-3.5" />
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
@@ -1758,10 +1760,10 @@ export function VideoGenNode({ data, selected }: any) {
|
||||
e.stopPropagation()
|
||||
d.onDeleteVideo?.(v.id)
|
||||
}}
|
||||
className="absolute right-1 top-1 z-[70] h-5 w-5 rounded-full bg-rose-500/90 text-white shadow-md backdrop-blur inline-flex items-center justify-center transition hover:bg-rose-400 hover:scale-110"
|
||||
className="absolute right-1.5 top-1.5 z-[70] inline-flex h-7 w-7 items-center justify-center rounded-full bg-rose-500/95 text-white shadow-lg backdrop-blur transition hover:scale-110 hover:bg-rose-400"
|
||||
title="删除这个视频任务"
|
||||
>
|
||||
<Trash2 className="h-2.5 w-2.5" />
|
||||
<Trash2 className="h-3.5 w-3.5" />
|
||||
</button>
|
||||
</div>
|
||||
)})}
|
||||
|
||||
Reference in New Issue
Block a user