From b542a80f892deabf802d0540117b538b7fde8041 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 6 Apr 2026 23:30:44 +0800 Subject: [PATCH] Restyle video canvas editor UI --- app/canvas/[id]/page.tsx | 97 ++++++++++++++---------- components/canvas/CanvasWorkspace.tsx | 35 ++++----- components/canvas/nodes/ImageNode.tsx | 69 ++++++++++------- components/canvas/nodes/VideoNode.tsx | 53 ++++++++----- components/canvas/nodes/WorkflowNode.tsx | 77 +++++++++++++++---- 5 files changed, 209 insertions(+), 122 deletions(-) diff --git a/app/canvas/[id]/page.tsx b/app/canvas/[id]/page.tsx index e31b29547..64842cb5d 100644 --- a/app/canvas/[id]/page.tsx +++ b/app/canvas/[id]/page.tsx @@ -732,19 +732,19 @@ const AGENT_RESULT_MODE_LABELS: Record = sku_replacement: "SKU 替换", }; const VIDEO_CANVAS_PANEL_CLASS = - "pointer-events-auto overflow-hidden rounded-[24px] border border-slate-200 bg-white text-foreground shadow-[0_16px_36px_-24px_rgba(15,23,42,0.2)] dark:border-zinc-800 dark:bg-zinc-950"; + "pointer-events-auto overflow-hidden rounded-[24px] border border-[#dbe2ee] bg-white text-[#16181d] shadow-[0_0_0_1px_rgba(219,226,238,0.42),0_24px_52px_rgba(22,24,29,0.08)] dark:border-zinc-800 dark:bg-zinc-950"; const VIDEO_CANVAS_PANEL_BADGE_CLASS = - "border-slate-200 bg-slate-50 text-foreground/70 dark:border-zinc-800 dark:bg-zinc-900"; + "border-[#d7dff0] bg-[#f6f8ff] text-[#5b6678] dark:border-zinc-800 dark:bg-zinc-900"; const VIDEO_CANVAS_SUBSECTION_CLASS = - "rounded-[18px] border border-slate-200 bg-slate-50 p-3 dark:border-zinc-800 dark:bg-zinc-900"; + "rounded-[18px] border border-[#e2e8f2] bg-[#f8faff] p-3.5 dark:border-zinc-800 dark:bg-zinc-900"; const VIDEO_CANVAS_TOOLBAR_CLASS = - "flex items-center gap-1.5 rounded-[28px] border border-slate-200 bg-white px-2.5 py-1.5 shadow-[0_18px_40px_-24px_rgba(15,23,42,0.24)] dark:border-zinc-800 dark:bg-zinc-950"; + "flex items-center gap-1.5 rounded-[26px] border border-[#dbe2ee] bg-white px-2.5 py-1.5 shadow-[0_0_0_1px_rgba(219,226,238,0.42),0_20px_42px_rgba(22,24,29,0.08)] dark:border-zinc-800 dark:bg-zinc-950"; const VIDEO_CANVAS_TOOLBAR_BUTTON_CLASS = - "h-9 w-9 rounded-xl border border-transparent text-foreground/75 hover:border-slate-200 hover:bg-slate-50 hover:text-foreground dark:hover:border-zinc-800 dark:hover:bg-zinc-900"; + "h-9 w-9 rounded-[14px] border border-transparent text-[#5b6678] hover:border-[#d9e1f2] hover:bg-[#f7f9ff] hover:text-[#16181d] dark:hover:border-zinc-800 dark:hover:bg-zinc-900"; const VIDEO_CANVAS_TOOLBAR_ACTIVE_BUTTON_CLASS = - "border-slate-200 bg-white text-foreground shadow-sm hover:bg-slate-50 dark:border-zinc-800 dark:bg-zinc-950 dark:hover:bg-zinc-900"; + "border-[#d6def7] bg-[#eef2ff] text-[#3954db] shadow-[0_0_0_1px_rgba(91,118,254,0.14)] hover:bg-[#e7edff] dark:border-zinc-800 dark:bg-zinc-950 dark:hover:bg-zinc-900"; const VIDEO_CANVAS_COMPACT_CONTROLS_CLASS = - "rounded-full border border-slate-200 bg-white px-2 py-1 shadow-sm dark:border-zinc-800 dark:bg-zinc-950"; + "rounded-full border border-[#dbe2ee] bg-white px-2 py-1 shadow-[0_0_0_1px_rgba(219,226,238,0.36),0_12px_26px_rgba(22,24,29,0.06)] dark:border-zinc-800 dark:bg-zinc-950"; function buildScopedCanvasChatId(projectId: string, scope: "agent-mode") { const normalized = String(projectId || "") @@ -1356,8 +1356,8 @@ export default function CanvasEditorPage({ params }: PageProps) { : null; const videoModuleSidebarWidth = isVideoMode ? isVideoModuleSidebarCollapsed - ? 56 - : 228 + ? 60 + : 264 : 0; const selectedWorkflowPanelLeft = isVideoMode ? videoModuleSidebarWidth + 24 @@ -8249,27 +8249,34 @@ export default function CanvasEditorPage({ params }: PageProps) { >
-
+
{isVideoModuleSidebarCollapsed ? (
- + + +
) : (
- + -
- 模块 +
+
+ 视频模块 +
+
+ 工作流分层添加 +
)}
{isVideoModuleSidebarCollapsed ? ( -
+
{VIDEO_CANVAS_SIDEBAR_GROUPS.map((group) => { const GroupIcon = group.icon; return (
) : ( -
+
{VIDEO_CANVAS_SIDEBAR_GROUPS.map((group) => { const GroupIcon = group.icon; return ( @@ -8324,23 +8331,28 @@ export default function CanvasEditorPage({ params }: PageProps) { } open={videoModuleSectionOpen[group.id] !== false} > -
+
- + - - {group.label} - +
+ + {group.label} + + + {group.description} + +
- + {group.nodeTypes.length} -
-
+
+
{group.nodeTypes.map((type) => { const definition = getVideoWorkflowNodeDefinition(type); @@ -8359,7 +8371,7 @@ export default function CanvasEditorPage({ params }: PageProps) { getVideoWorkflowQuickConnectIcon(type); return ( @@ -8427,9 +8440,9 @@ export default function CanvasEditorPage({ params }: PageProps) { d={`M 0 0 C ${cp1X} 0, ${cp2X} ${y}, ${targetX} ${y}`} fill="none" key={`quick-connect-line-${item.type}`} - stroke="rgba(59,130,246,0.9)" + stroke="rgba(91,118,254,0.92)" strokeLinecap="round" - strokeWidth="2.5" + strokeWidth="2.25" /> ); })} @@ -8437,7 +8450,7 @@ export default function CanvasEditorPage({ params }: PageProps) { @@ -3254,14 +3271,14 @@ export function ImageNode({ node, isSelected }: ImageNodeProps) { {/* 提示词显示 */} {data.prompt && isHovered && !isProcessing && ( -
-

{data.prompt}

+
+

{data.prompt}

)} {data.note && !isSelected && (
@@ -3271,7 +3288,7 @@ export function ImageNode({ node, isSelected }: ImageNodeProps) { {shortAgentExecutionSnapshotId ? ( {/* 底部控制栏 */} -
+
{/* 进度条 */} {isPlaying ? ( @@ -203,7 +205,7 @@ export function VideoNode({ node, isSelected }: VideoNodeProps) {
) : data.status === 'generating' ? ( -
- - 生成中... +
+ + + + 生成中... {data.progress && ( - {data.progress}% + {data.progress}% )}
) : data.status === 'failed' ? ( -
- - 生成失败 +
+ + + + 生成失败
) : ( -