P1-05 · pixi:RenderTextureBackend(normal 绘制 + 显示 + 撤销)
- Phase / ID: P1 / P1-05
- Depends on: P1-02(契约)、P1-01
- Files:
packages/pixi/src/{RenderTextureBackend,dab-cache}.ts、test/ - Effort: L
- Status: 🔴 P1 核心
Context
实现 SurfaceBackend:每图层一张 RenderTexture,戳印渲染进 RT(不进 scene graph,所以画多少笔节点数都不涨)。撤销用受影响 bbox 的区域快照(D4,禁止全画布快照)。本卡只做 normal 绘制 + undo;erase 在 P1-06。
关键取舍——scratch RT 方案:当前笔迹画进一张共享
strokeRT(透明),endStroke时才按 bbox 合成进图层committedRT。这样:① 撤销 before/after 只需读 bbox 区域;② 天然支持后续「整笔不透明度 / erase 合成」。直接画进 committed 会导致「before 必须在落第一笔前快照、但 bbox 未知」——故否决。
Steps
- 构造:
new RenderTextureBackend({ renderer, stage }),stage是要挂图层 Sprite 的容器(P1-08 传入现有canvas.layersContainer,使其随 board 变换)。 createLayer(id):committedRT = RenderTexture.create({ width, height });sprite = new Sprite(committedRT),加入stage;登记id → { committedRT, sprite }。- dab 缓存:预渲染一张软/硬圆 dab 纹理(一次),
paintDab复用并按radius缩放、按color/opacitytint——避免每 dabnew Graphics(5000 dab 性能)。 beginStroke(layerId):清空共享strokeRT,dirty = DirtyRect.empty(),挂strokeSprite到该层做实时预览。paintDab(layerId, dab, 'normal'):把 dab 节点定位到dab.x/y、缩放到radius、tint=color、alpha=opacity,renderer.render({ container: dabNode, target: strokeRT, clear: false });dirty = union(dirty, fromCircle(dab));返回该 dab 的DirtyRect。endStroke(layerId):before = extract.pixels({ target: committedSprite, frame: dirty })(v8 返回{ pixels, width, height })。- 把
strokeRT的dirty区域合成进committedRT(renderer.render({ container: strokeSprite, target: committedRT, clear: false }))。 after = extract.pixels({ ..., frame: dirty });清strokeRT/ 收起预览。- 返回
StrokePatch{ layerId, rect: dirty, before, after }。
applyPatch(patch, dir):取dir==='undo'?before:after,写回committedRT的rect区域。子区域替换要点:先用 erase 把该 rect 清零,再把快照像素作为 Texture(normal)画回;注意 Pixi premultiplied alpha(用 P1-02 的 premultiply 辅助核对)。getDisplayHandle(id)返回该层sprite(core 不依赖其类型)。
Acceptance
- [ ]
createLayer后画布出现该层 sprite,可被 board 缩放 / 平移带动。 - [ ] 连续 5000 dab,
stage子节点数不增长(dab 进 RT,非场景图)——计数断言。 - [ ] golden:画一笔 →
endStroke后 committed 像素与基准一致。 - [ ] undo→redo 后该层像素与各时刻一致(区域回写正确,含 alpha)。
Out of scope
- erase(→ P1-06)。
- tile(→ P2);带 transform 图层(→ P6)。