P1-08 · 集成:把 pixi-painter 的 brush/eraser 切到新管线
- Phase / ID: P1 / P1-08
- Depends on: P1-03、P1-04、P1-05、P1-06、P1-07;运行依赖 P0-02
- Files:
packages/pixi-painter/src/{painter,brush/index,eraser/index,canvas/index,features/history}.ts - Effort: L
- Status: 🔴 把前面所有件接成可用
Context
把现有「每笔一个 Graphics」替换成 core + RenderTextureBackend 管线,对外 API 尽量不变(useTool / painter.brush.setSize / history.undo)。pixi-painter 依赖 @saier/core + @saier/pixi。
Steps
- 装配(在
painter.init(),P0-02 之后):const backend = new RenderTextureBackend({ renderer: app.renderer, stage: canvas.layersContainer })。const doc = new Document();建一个默认RasterLayer并backend.createLayer(layer.id)、doc.setActive(layer.id)。const undo = new UndoManager(); undo.attach(backend)。const engine = new SimpleBrushEngine();const controller = new PainterController(...)。
- brush 管线(重写
brush/index.ts的 pointer 流程,保留类名 / 公共方法):pointerdown:engine.beginStroke({ color, baseSize });backend.beginStroke(activeLayerId)。pointermove:const docPt = toDocument(event)(用现有getLocalPosition(canvas.layersContainer),P1 仅支持未变换图层,见 interfaces · 坐标);engine.addPoint(docPt).forEach(d => backend.paintDab(activeLayerId, d, 'normal'))。pointerup/out:engine.endStroke().forEach(...paintDab);const patch = backend.endStroke(activeLayerId); undo.record(patch)。- 删掉旧的
new Graphics()累积绘制与graphicsPool。
- eraser:同 brush,但
paintDab(..., 'erase');删掉画白逻辑。 - history 对接:
PainterHistory.undo/redo委托给UndoManager(或直接用 UndoManager 并保留painter.history.undo()包装),保持现有键盘快捷键可用。 - 保留:brush 光标圈、
EditableLayer图片导入 / 变换、selection、缩放平移(都是 Pixi overlay / 视图层,按 D7 不动)。 painter.brush.setSize/setColor等转调controller(不再写PainterBrush静态——若一步到位有风险,可暂留静态读、但新绘制走 engine 的值,UI 静态清理留 P5)。
Acceptance
- [ ]
examples/vue:brush 连续画线、改尺寸/颜色生效;eraser 真擦透明;undo/redo 正常。 - [ ] 一次 stroke 不再新增
Graphics子节点;连续多笔stage子节点数稳定。 - [ ] 图片导入 + 变换 + selection + 缩放平移仍工作(未回归)。
- [ ]
pnpm typecheck/lint绿。
Out of scope
- 在被缩放 / 旋转的图层上绘画(→ P6)。
- 多笔刷类型 / stabilizer(→ P3/P4);UI 去静态字段(→ P5)。