diff --git a/.memory/worklog.json b/.memory/worklog.json
index 8a10f0b..28011a5 100644
--- a/.memory/worklog.json
+++ b/.memory/worklog.json
@@ -2175,6 +2175,13 @@
"type": "session-heartbeat",
"message": "Codex 会话活跃 · 最近命令:codex · 1 项未提交变更 · 最近提交:auto-save 2026-05-13 19:06 (~3)",
"files_changed": 1
+ },
+ {
+ "ts": "2026-05-13T19:12:17+08:00",
+ "type": "commit",
+ "message": "auto-save 2026-05-13 19:12 (~3)",
+ "hash": "61a4bec",
+ "files_changed": 3
}
]
}
diff --git a/docs/source-analysis.html b/docs/source-analysis.html
index 575283a..2a746dd 100644
--- a/docs/source-analysis.html
+++ b/docs/source-analysis.html
@@ -595,7 +595,7 @@
前端主链路:
web/app/page.tsx
-> ReactFlow 节点:web/components/nodes/index.tsx
- -> 镜头拆解面板:web/components/lightbox.tsx
+ -> 画布内镜头拆解面板:KeyframeNode 内嵌 web/components/lightbox.tsx
-> 顶部分镜条:web/components/storyboard-bar.tsx
-> 分镜工作台:web/components/storyboard-workbench.tsx
-> API 契约:web/lib/api.ts
@@ -617,8 +617,8 @@ api/main.py
你看到的区域镜头拆解节点上方关键帧
-
主要源码KeyframeNode 和 FrameLightbox;后端 /frames、/describe、/cleanup。
-
适合怎么描述“关键帧选用、清洗、识别、元素提取的操作顺序要怎么组织”。
+
主要源码KeyframeNode 内嵌 FrameLightbox;后端 /frames、/describe、/cleanup。
+
适合怎么描述“关键帧详情面板在无限画布上怎么展示、缩放、跟随,以及清洗/识别/元素提取的操作顺序”。
你看到的区域元素列表和提取图
@@ -830,6 +830,17 @@ api/main.py
变更记录
这个记录不是 git log 的替代品。它记录“产品理解发生了什么变化、影响了哪些源码、你以后描述需求时该怎么说”。后续每次改功能都要补一条。
+
+
+ 2026-05-13 · 关键帧详情从固定左侧抽屉迁到无限画布
+ KeyframeNode
+
+
+
问题:关键帧详情 / 元素提取面板固定在左侧 drawer,和 ReactFlow 无限画布割裂,也不会跟随画布缩放。
+
改动:移除主页面隐藏渲染的 Dashboard drawer 承载方式,改为在 KeyframeNode 内部挂载 FrameLightbox,作为画布上的工作面板。
+
影响:web/app/page.tsx、web/components/nodes/index.tsx;点关键帧后面板会跟随 ReactFlow 平移和缩放。
+
+
2026-05-13 · 元素改造 hover 预览简化为原帧预览
diff --git a/web/app/page.tsx b/web/app/page.tsx
index 447e948..5d01f9f 100644
--- a/web/app/page.tsx
+++ b/web/app/page.tsx
@@ -13,7 +13,6 @@ import {
type NodeData,
} from "@/components/nodes"
import { ThemeToggle } from "@/components/theme-toggle"
-import { Dashboard, type DashboardHandle } from "@/components/dashboard"
import { StoryboardBar } from "@/components/storyboard-bar"
import { StoryboardWorkbench } from "@/components/storyboard-workbench"
import { addManualFrame, analyzeJob, createJob, getJob, uploadJob, deleteFrame, deleteGeneratedImage, type Job, type ImageRef } from "@/lib/api"
@@ -69,7 +68,6 @@ export default function Home() {
const [storyboardFrame, setStoryboardFrame] = useState(null)
const [workbenchOpen, setWorkbenchOpen] = useState(false)
const [clipboard, setClipboard] = useState(null)
- const dashboardRef = useRef(null)
// 把 setJob(prev=>...) 翻译成 setJobs 里更新当前 active
const setJob = useCallback((updater: Job | ((prev: Job | null) => Job | null) | null) => {
@@ -283,7 +281,6 @@ export default function Home() {
onOpenVideoLightbox: () => setVideoLightboxOpen(true),
onSwitchJob: handleSwitchJob,
onJobUpdate: setJob as any,
- onOpenPanel: (key: string) => dashboardRef.current?.openPanel(key),
onDeleteFrame: handleDeleteFrame,
onDeleteGenerated: handleDeleteGenerated,
onOpenStoryboard: (idx: number) => setStoryboardFrame(idx),
@@ -337,11 +334,6 @@ export default function Home() {
- {/* sidebar tile 列已去掉 · Dashboard 仍渲染(hidden)以保留 keyframe lightbox 等 drawer portal */}
-
-
{/* 右区:顶部 storyboard bar + DAG 节点流图 */}
- {/* FrameLightbox 已嵌入 dashboard 的 keyframe drawer(embedded mode),不再独立浮动 */}
-
{/* Video lightbox — InputNode 缩略图点击进入 */}
+ {/* 关键帧详情 / 元素提取:作为无限画布上的工作面板,跟随 ReactFlow 缩放和平移 */}
+ {d.job && d.expandedFrame !== null && (
+ e.stopPropagation()}
+ onWheel={(e) => e.stopPropagation()}
+ >
+
+
+ )}
+
)
}