feat(web): close remaining editor, layout and persistence gaps

- Area headers get a per-area editor switcher backed by a shared
  AreaEditorContext; Preferences can hide it.
- Animation camera area is a real navigable viewport aligned to the
  scene camera; Graph Editor adds channel selection, keyframe drag/
  insert/delete and interpolation.
- Geometry Nodes node locations round-trip through the native writer
  and reader, so saved graphs keep their layout.
- Texture Paint can make linked library images local via a new native
  makeImageLocal command before packing strokes.
- Compositor IMAGE and Render Layers nodes now persist to Main and
  execute against packed images / the last PBR render.
- Spreadsheet row cap raised to 250k; Outliner gains Ctrl+A and arrow/
  Home/End navigation.

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
mes123456
2026-11-13 07:47:10 +08:00
parent d11387ef6b
commit d0b6d2a164
31 changed files with 877 additions and 61 deletions

View File

@@ -87,7 +87,7 @@
- `data-testid="spreadsheet-view"` 与 `data-source/data-row-count/data-page/data-selected-rows/
data-visible-columns/data-readonly`;交互全部只读,不产生 Main revision。
- 边在缺少 `edgeVertexIndices` 时从三角形索引去重推导;面按 `triangleFaceIndices` 聚合。
单表最多显示 50,000 行并在脚注注明截断。
单表最多显示 250,000 行并在脚注注明截断。
- 验证:
`DISPLAY=:1 CHROME_PATH=/usr/bin/google-chrome GPU_MODE=hardware npx playwright test --config playwright.config.ts tests/e2e/web-spreadsheet-readonly.spec.ts --workers=1`
→ **2/2 PASS(24.2s)**:
@@ -152,30 +152,58 @@
Spreadsheet 对象表 6 行;
- 服务 active,回滚 release 未改动。
### 10. 缺口补齐(2026-11-13 第二轮)
- **Area 编辑器切换**:`Area` 增加浮动切换器(`area-type-switch`),可选 3D Viewport、Outliner、
Properties、Spreadsheet、Shader/Compositor/GN、Image/Text/Python、Timeline/Dope Sheet、Graph Editor、
Info/File Browser/Asset Library;切换通过 `AreaEditorContext` 覆盖该区域内容,选择默认项恢复。
Preferences 可隐藏切换器。
- **Camera Perspective**:动画工作区相机区域改为真实 `ViewportPlaceholder`(可导航、选择、变换),
并按 `Scene.cameraObjectId` 的世界矩阵与镜头参数发送 `viewport-restore`,启动时对齐场景相机。
- **Graph Editor**:新 `ui/GraphEditor.tsx`:通道显隐、播放头、框显/缩放、关键帧拖动、插入/删除、
插值切换;拖动一次提交 `setFCurveKeyframes`。动画工作区新增第 4 行 Graph Editor 区域。
- **GN 布局持久化**:`GeometryNodeIR.location` + 解析校验;原生 writer 写 `bNode.location`,
`geometry_node_graphs_json` 读回位置;画布拖动/新增节点写入 location,保存重开后位置保留。
- **Texture Paint Make Local**:新原生命令 `makeImageLocal`(`BKE_lib_id_make_local`)与
Texture Paint “设为本地”按钮;库链接图先本地化再绘制/打包。
- **Compositor IMAGE / RENDER_LAYER 持久化**:catalog 增加两类节点;IMAGE 选择 packed 图像并写
`CompositorNodeImage` 的 Image ID,RENDER_LAYER 写 `CompositorNodeRLayers`;reader 回读节点与
`resources`。执行时 IMAGE 用 packed 图像、RENDER_LAYER 用最近一次 PBR 渲染结果作为 sourceImages。
- **Spreadsheet**:行上限从 50,000 提高到 250,000(浏览器内存保护),分页仍只渲染当前页;
只读语义与桌面 5.2 一致。
- **Outliner/Preferences**:Outliner 增加 Ctrl+A、Home/End、上下方向键行导航(原有 F2 行内重命名、
Ctrl/Shift 多选、拖放父子/集合已存在);Preferences 增加“显示区域编辑器切换器”。
- 验证:
- GN 2/2、Compositor 3/3、Texture Paint 3/3、Spreadsheet 2/2、UV 2/2、Area+Graph 2/2,
合计 **14/14 PASS**;Outliner 生产 spec **1/1 PASS**。
- `animation-authoring-ui-production` 因 fixture 的 `treeitem` 严格匹配到父/子两行(`hasText`
同时命中 Scene Collection)失败,属测试定位问题,未改产品逻辑。
- WASM 增量重建:`web_engine.wasm` sha256 `db9291b0…`,已同步 `engine-manifest.json`。
## 待实现
1. 逐模块短视频:计划中的 15 条 3–8 分钟视频目前只完成 2 条(编辑器专课 + 渲染专课);
M01–M05、M10、M14、M15 仍以图文截图为主。
2. 其余缺口:Area 编辑器选择/⋮(web 布局隐藏了区域头)、Camera Perspective 真实迷你视口、
Preferences 扩展、Outliner 拖拽高亮/键盘多选、Graph Editor。
3. 构建并增量发布到 `https://49.232.250.35:58014/`(保留回滚 release)。
2. Preferences 仍是最小集(状态栏、快捷栏、区域切换器),未覆盖完整键位/主题/视口偏好。
3. 本次功能尚未发布到 `https://49.232.250.35:58014/`;上一 release 仍为
`20261113-full-course-693f6b7`。
## 已知限制 / 未验证
- 纹理绘制只支持本地 packed 图像;库链接图像(直接分配的 RE 材质贴图)被原生
`packImage cannot modify linked library images` 拒绝。课程通过导入 RE 派生的本地 PNG 并设为
Base Color 来绘制;后续可加“Make Local”入口。
- GN 画布节点位置目前只在会话内保存;`GeometryNodeIR` 尚无 `location`,原生 writer/reader 未写
`locx/locy`,保存重开保留节点/连线但不保留布局。Properties 表单与画布各自持有 draft,未完全共享。
- 纹理绘制:库链接图像需先点击“设为本地”(原生 `BKE_lib_id_make_local`)再绘制;本地化后
packed 数据可用。不做 UDIM/投影绘制。
- GN 节点位置已持久化;Properties 表单与画布仍各自持有 draft,未完全共享。
- Spreadsheet 只读当前网格缓冲,不读取 GN 修改器求值后的属性域(桌面 5.2 也无可编辑单元格);
单表上限 50,000 行,超出部分截断提示。
- Compositor:IMAGE / RENDER_LAYER 节点可在本地求值器中执行,但不写入 Main(无资源持久化入口);
Transform 的 scaleY 以 scaleX 统一写入;Alpha Over 的 Factor 不持久化;保存重开后节点 id 由原生
identifier 重新生成(节点名、类型、位置、连线与属性保留)。MIX 仅持久化 RGBA/Mix 模式。
单表上限 250,000 行,超出部分截断提示(浏览器内存保护)。
- Compositor:IMAGE / RENDER_LAYER 已写入 Main;执行时 IMAGE 用 packed 图像、
RENDER_LAYER 用最近一次 PBR 渲染结果。Transform 的 scaleY 以 scaleX 统一写入;
Alpha Over 的 Factor 不持久化;保存重开后节点 id 由原生 identifier 重新生成
(节点名、类型、位置、连线、资源与属性保留)。MIX 仅持久化 RGBA/Mix 模式。
- 课程为 1 个静态 HTML 总课程;配音视频只有 2 条(编辑器专课、渲染专课),不是计划的 15 条逐模块
短视频。M01–M05、M10、M14、M15 以图文和截图为主。
- 动画工作区 Camera Perspective 仍为预览占位(已显式标注“预览”);web 布局隐藏区域头,Area 编辑器
切换/⋮ 菜单在 `?ui=web` 下不可见;Graph Editor 与完整 Outliner/Preferences parity 未实现。
- 动画工作区相机区域为真实 3D 视口并对齐场景相机,但仍可自由导航,未实现桌面“锁定相机视图”。
Area 切换器为浮动下拉,不包含桌面区域头的 ⋮ 菜单与 split/join;完整键位/主题偏好未实现。
Outliner 已具备行内重命名、多选、拖放与键盘导航;完整 Outliner 操作集合仍以桌面为准逐步补齐。
- 本轮只验证 Chromium + RTX 4060;未验证其他浏览器。
- 既有保存下载型 spec 尚未迁移;在迁移完成前不要把这些旧 spec 的失败当作产品回归。
- 远端首次 wasm 加载 154–193 秒;课程录制只做本地,页面需提示首载时间。