Files
labelimage/5168f53_polygon_brush_point_edit_fix.md

4.5 KiB
Raw Blame History

5168f53 回归分析与修复记录

问题描述

  • 提交:5168f539e0dbf84d6a1625d10ef98149fb21ffe6
  • 现象:polygon / brush / point 类型对象在被选中后,无法通过鼠标悬浮边触发边高亮,也无法通过双击边新增点。

usePaperStore 关键链路梳理

  1. 选中对象

    • 入口主要在 components/label/usePaperStore.tsinitPanTool -> panTool.onMouseDown
    • 通过 resolvePanHitResult() 命中对象、辅助边(pathBuff)或辅助点(pathCircle)
    • 选中后会调用:
      • usePaperSupportStore.handleBufferPaths() 生成可 hover / 可双击的辅助边
      • usePaperSupportStore.handleCircles() 生成可拖拽节点
      • usePaperSupportStore.handleMask() / handleText() 生成刷子/点类型附加辅助层
  2. 悬浮边高亮

    • usePaperSupportStore.handleBufferPaths() 会遍历 path 的 segment调用 usePaperStore.getBuffPath() 为每条边创建 pathBuff
    • getBuffPath() 中给 bufferPath 绑定 onMouseEnter / onMouseLeave
    • 悬浮时通过额外创建 pathBuffHover 白色描边来实现高亮
    • 同时把当前 hover 信息记入 hoveredBufferPathInfo
  3. 双击边新增点

    • 仍然在 panTool.onMouseDown
    • 双击判定由 isPaperDoubleClick() 完成
    • 命中 pathBuff 或存在 hoveredBufferPathInfo 时,会走 stroke 分支或 hoveredBufferInfo 分支
    • 最终通过 path.insert(hitIndex + 1, point) 新增节点
  4. 右侧/外部选择对象后的恢复链路

    • components/label/utils/objectVisibility.tssyncSelectedObjectsVisualState() 负责根据 selectedPath 重新恢复画布上的选中态
    • 该链路也必须正确恢复:
      • 选中的实际可编辑 path
      • 辅助边 pathBuff
      • 辅助点 pathCircle
    • 否则对象虽“被选中”,但无法进入边 hover / 双击增点链路

回归根因

根因 1辅助边被改成完全透明导致命中/hover 链路失效

  • getBuffPath() 中,pathBuff.strokeColor 被改成了完全透明的颜色
  • 这会导致 pathBuff 在某些情况下不再稳定触发 hover / hit 行为
  • 后果:
    • hoveredBufferPathInfo 无法建立
    • 边高亮不出现
    • 双击新增点依赖的 pathBuff 命中链路失效

根因 2选中态恢复时没有稳定选中“真正可编辑的 path”

  • polygon / brush / point 可能存在 CompoundPath + child Path 的结构
  • 之前恢复选中态时,更多是“对象被选中”,但没有保证“某个可编辑 child path 被明确选中并生成辅助边/辅助点”
  • 后果:
    • 外部选中/恢复选中后,缺少 pathBuff
    • 即使对象看起来是选中状态,也无法 hover 边、双击增点

修复方案

已做

  • components/label/usePaperStore.ts 中新增 ensureEditablePaperPathSelected()

    • 统一从同一对象 id 下挑出一个真实可编辑的 paper.Path
    • 排除 isHollowPolygon
    • 保证只有该可编辑 path 维持 selected = true
  • 修复 applyPaperSelectedPath()

    • polygon / brush / point 不再只依赖当前 item 是否刚好是 paper.Path
    • 改为统一拿到可编辑 path 后恢复:
      • handleBufferPaths
      • handleCircles
      • handleMask
      • handleText
  • 修复 components/label/utils/objectVisibility.ts 中的 applySelectedItemVisual()

    • 保证右侧面板/隐藏恢复/重绘恢复时,同样能恢复到真实可编辑 path 的辅助编辑态
  • 修复 getBuffPath() 的命中可用性

    • 不再使用 alpha 为 0 的完全透明描边
    • 改为极低透明度(alpha = 0.001)以保留 hover/hit 能力,同时视觉上保持不可见
  • 完成静态校验

    • 执行 pnpm exec tsc --noEmit
    • 当前补丁未引入新的 TypeScript 类型错误

待验证

  • 直接点击已存在 polygon 对象后,悬浮边是否出现高亮
  • 直接点击已存在 polygon 对象后,双击边是否成功新增点
  • 直接点击已存在 brush 对象后,悬浮边是否出现高亮
  • 直接点击已存在 brush 对象后,双击边是否成功新增点
  • 直接点击已存在 point 对象后,悬浮边是否出现高亮
  • 直接点击已存在 point 对象后,双击边是否成功新增点
  • 从右侧对象列表切换选中后,上述三类对象是否仍可编辑
  • 多区域/CompoundPath 对象时,是否总能命中当前可编辑子路径

涉及文件

  • components/label/usePaperStore.ts
  • components/label/utils/objectVisibility.ts
  • 5168f53_polygon_brush_point_edit_fix.md