Skip to content

场景与增量 ​

场景是“已经可以画出来的零件清单”。它不再关心文档语义,也不再计算布局,只保存绝对几何 和已经解析好的样式。

正在渲染图表…

一个场景由什么组成 ​

每个零件都有唯一的 key、绝对坐标和 Style。零件可以带 ref,宿主做选择、悬停或拖拽时 直接读 { kind, id, part? },不必解析 key 字符串。

场景的顺序本身就是绘制顺序:

  1. 画布底;
  2. 容器背景;
  3. 边和箭头;
  4. 叶子节点;
  5. 边标签。

所以“线在节点下面、标签在节点上面”不需要 z-index,也不需要宿主自己排序。

key 为什么重要 ​

增量更新不是比较整张 SVG,而是按 key 比较场景树。稳定 key 让宿主知道“这是同一个节点” 和“这是同一个标签”;key 一变,宿主只能删掉旧子树再重新创建。

节点注册时用 ctx.out.key(suffix) 生成 key,不要用随机数、时间或数组下标。复合形状的子 key 会自动带上父前缀,因此 icon 和 button/icon 不会互相覆盖。

diff 怎么判断变化 ​

变化结果
同一个 key,几何或样式变了update
新增 key 或 kind 变了create
节点被删除remove
已有 key 的兄弟顺序变了move,不重建子树

插入或删除兄弟不会误触发 move;只有仍在场的 key 相对顺序改变时才发送 move。 hitTest(scene, point) 用场景几何从上到下返回 SceneRef[],适合选择框和点击命中。

diff 的目标是结果等价,不是生成尽可能少的 patch。这样规则简单,宿主也容易实现。

常见误解 ​

  • key 不稳定,就会把普通修改变成整棵子树重建。
  • 场景里的坐标已经是绝对值,宿主不能再按父节点二次变换。
  • diff 不负责布局;它只比较两份已经构建好的场景。
  • 场景顺序有语义,手动重排可能改变遮挡关系。
  • Scene.bounds 是内容边界,overflow 单独记录阴影 / 发光溢出;相机边距由 host 解释。

MIT License