让新建绘制并入选中遮罩

- 多边形、矩形、圆和画笔在当前已有选中 mask 时,将新几何 union 并入选中 mask,即使区域不重叠也保持为同一个多 polygon mask。

- 无选中 mask 时仍按原新建流程创建并自动选中新 mask;画笔无选区时仍要求右侧语义分类树有选中类别。

- 补充 CanvasArea 回归测试,覆盖创建工具保留选区、分离矩形并入选中 mask、画笔无 active class 时并入选中 mask。

- 更新前端审计、需求冻结、设计冻结、状态机、测试计划和项目指南文档。
This commit is contained in:
2026-05-04 04:57:53 +08:00
parent 1971640a67
commit 85de1ffbb2
9 changed files with 118 additions and 44 deletions

View File

@@ -183,8 +183,8 @@
3. 多边形工具逐次记录节点,三点后点击首节点或按 Enter 时生成闭合 polygon。
4. Canvas 左上角根据当前工具和操作阶段显示上下文短提示;多边形提示会随已放置点数切换,明确 Enter 完成、Esc 取消和点击首节点闭合。`Esc` 和左侧工具栏“取消选中”按钮只取消当前 mask 选区、临时多边形点、矩形/圆拖拽状态、画笔/橡皮擦临时笔触和顶点选择,不删除已有 mask也不清空右侧语义分类树的当前类别。提示会在工具或操作状态变化时出现并在数秒后自动隐藏避免长期遮挡底图。
5. mask path 只在 `move``edit_polygon``area_merge``area_remove` 工具下拦截点击;绘制、画笔、橡皮擦和 AI prompt 工具点击已有 mask 时继续冒泡给 Stage。
6. 画笔/橡皮擦尺寸保存在 Zustand 中;拖动期间只保留采样后的圆形笔触预览,鼠标松开后再用 `polygon-clipping` 计算一次几何结果,避免拖动中反复重算复杂 polygon。画笔把本次采样笔触 union 成一个新的独立 mask不与当前选中 mask 自动合并;如果画笔笔触闭合形成中空区域,`segmentation` 保留外圈和内洞 ring`metadata.hasHoles/polygonRingCounts` 记录 ring 分组,并使用 even-odd 渲染;橡皮擦则对当前选中 mask 执行 difference 扣除。
7. 多边形、矩形、圆和画笔创建新 mask 写入 `pathData`、像素 `segmentation``bbox``area` 和当前模板分类元数据,并自动写入 `selectedMaskIds` 成为当前选中 mask。若右侧没有选中具体分类新建 mask 默认使用 `maskid: 0` 的“待分类”。创建工具仍处于激活状态时,刚创建选中 mask 会显示只读边界顶点;切换到 `move` 或“调整多边形”后这些顶点可拖动编辑。
6. 画笔/橡皮擦尺寸保存在 Zustand 中;拖动期间只保留采样后的圆形笔触预览,鼠标松开后再用 `polygon-clipping` 计算一次几何结果,避免拖动中反复重算复杂 polygon。画笔有选中 mask 时会把本次采样笔触 union 进选中 mask即使笔触和旧区域不重叠也形成同一个多 polygon mask没有选中 mask 时才按当前语义分类创建新的独立 mask;如果画笔笔触闭合形成中空区域,`segmentation` 保留外圈和内洞 ring`metadata.hasHoles/polygonRingCounts` 记录 ring 分组,并使用 even-odd 渲染;橡皮擦则对当前选中 mask 执行 difference 扣除。
7. 多边形、矩形、圆和画笔完成时,如果当前帧有选中 mask会把新几何 union 进该 mask保留原 mask 的语义分类并将已保存 mask 标为 dirty如果当前没有选中 mask创建新 mask写入 `pathData`、像素 `segmentation``bbox``area` 和当前模板分类元数据,并自动写入 `selectedMaskIds` 成为当前选中 mask。若右侧没有选中具体分类新建 mask 默认使用 `maskid: 0` 的“待分类”。创建工具仍处于激活状态时,刚创建/被并入的选中 mask 会显示只读边界顶点;切换到 `move` 或“调整多边形”后这些顶点可拖动编辑。
8. `addMask()``setMasks()``updateMask()``clearMasks()` 会维护 `maskHistory/maskFuture`
9. 工作区撤销/重做只保留顶栏按钮和快捷键入口AI 页保留自己的撤销/重做按钮;工作区由 `VideoWorkspace` 在 window capture 阶段统一处理 `Ctrl/Cmd+Z``Ctrl/Cmd+Shift+Z``Ctrl/Cmd+Y`,快捷键判断由 `src/lib/keyboardShortcuts.ts` 同时兼容 `event.key` 与物理键码 `event.code=KeyZ/KeyY`;输入框、下拉框和可编辑文本聚焦时跳过快捷键,避免影响帧范围输入。
@@ -230,7 +230,7 @@
4. 后端把 `classes``rules` 打包进 `mapping_rules`
5. 返回时再解包给前端。
6. 模板详情页和编辑弹窗都支持拖拽调整语义类别层级顺序;拖拽后重算 `zIndex`,保存到后端模板并刷新当前详情页,`maskId` 保持不变。所有模板都会归一化包含黑色 `maskId: 0` 的“待分类”保留类,该类固定在语义分类树最后,不参与删除和拖拽上移。编辑弹窗点击分类后只编辑分类名称,不展示或编辑旧 `category` 来源元信息。编辑弹窗中的 JSON 批量导入支持 `[[colors], [names]]``{colors, names}` 两种格式,并兼容带前缀、代码块、未加引号 keys、单引号、中文逗号/冒号和尾随逗号的粘贴内容导入前会先显示分类数量、maskid 分配起点和缺失颜色提示,语法或结构错误以内联错误展示,确认导入后进入编辑态,保存模板时落库。
7. `CanvasArea` 把当前选中的 mask id 同步到全局 `selectedMaskIds`;切换到多边形、矩形、圆、AI prompt 等非选区创建工具时会清空旧 mask 选区,切换到移动、调整多边形、画笔、橡皮擦、区域合并或重叠区域去除时保留当前选区供用户继续参照或操作。切换帧时会优先沿传播链跟随同一 mask找不到对应结果时才清空卸载 Canvas 时清空选择。
7. `CanvasArea` 把当前选中的 mask id 同步到全局 `selectedMaskIds`;切换到多边形、矩形、圆、画笔、橡皮擦、移动、调整多边形、区域合并或重叠区域去除时保留当前选区,创建工具会把新几何并入当前选中 mask只有 `Esc`、左侧“取消选中”、删除 mask、AI prompt 等显式离开选区的动作会清空旧 mask 选区。切换帧时会优先沿传播链跟随同一 mask找不到对应结果时才清空卸载 Canvas 时清空选择。
8. `AISegmentation` 生成 mask 后会写入全局 `masks` 并把生成的 mask id 写入 `selectedMaskIds`;点击 AI 页预览 mask 也会更新 `selectedMaskIds`
9. AI 页“推送至工作区编辑”会先检查待推送 AI 候选 mask 是否具备 `classId``className`;缺少语义分类时清空普通推理反馈,并通过 `TransientNotice` 右上角 error toast 提示用户先点右侧语义分类树,不切换模块、不修改工具状态。
10. `AISegmentation` 卸载时会清理仍缺少 `classId/className` 的本页 AI 候选,并同步移除对应 `selectedMaskIds`,避免用户绕过推送按钮从侧栏切到工作区时带入无语义 mask。