Problem
penmode("erase") in turtle scripts has no effect on shapes created via rectangle(), ellipse(), polygon(), or star(). Erase only works on line-segment strokes created by movement commands (forward, goto_pos, etc.).
This means scripts cannot erase through or delete shapes — the erase path simply passes over them with no effect.
Root Cause
Three architectural factors:
-
Separate storage — Shapes and strokes are stored in different CRDT collections (doc.addShape() vs doc.addStroke()). eraseAlongSegment() in TurtleDrawing.ts:132 only queries doc.getStrokes(), never doc.getShapes().
-
Incompatible geometry — lineIntersectsStroke() in turtleEraseUtils.ts performs segment-to-segment hit-testing against a stroke's point array. Shapes don't have point arrays — they have type/width/height/position, requiring different intersection logic.
-
Whole-object removal — The current erase model removes entire strokes that intersect the erase path. It does not split, clip, or carve. This means even if shapes were included, erasing "through" a rectangle would delete the entire rectangle, not cut a hole in it.
Relevant Files
src/turtle/TurtleExecutor.ts — Lines 330-351 (erase dispatch), 358-406 (shape creation, ignores pen mode)
src/turtle/TurtleDrawing.ts — Lines 132-168 (eraseAlongSegment, only checks strokes)
src/turtle/turtleEraseUtils.ts — lineIntersectsStroke() (segment-based hit-testing)
src/crdt/DrawfinityDoc.ts — addShape() / removeShape() (separate from stroke storage)
Proposed Fix (Two Tiers)
Tier 1: Erase deletes whole shapes (easy)
Add shape hit-testing to eraseAlongSegment():
- Query
doc.getShapes() alongside doc.getStrokes()
- Implement bounding-box or geometric intersection tests for each shape type (rect → AABB test, ellipse → point-in-ellipse, polygon/star → bounding circle)
- Call
doc.removeShape() for intersecting shapes
- Estimated scope: ~100-200 lines across 2-3 files
Tier 2: Pixel-level carving (hard)
Allow erasing to cut holes in shapes (e.g., carve a smiley face into a circle):
- Would require converting shapes to clipping paths or decomposing them into segments
- Fundamentally different rendering model — shapes would need to support boolean geometry operations
- Significant effort, likely a separate feature initiative
Workaround
Scripts can simulate carving by overdrawing shapes with the canvas background color instead of using erase mode. See the "Smiley Face" example in docs/turtle-scripts-pending.md.
🤖 Generated with Claude Code
Problem
penmode("erase")in turtle scripts has no effect on shapes created viarectangle(),ellipse(),polygon(), orstar(). Erase only works on line-segment strokes created by movement commands (forward,goto_pos, etc.).This means scripts cannot erase through or delete shapes — the erase path simply passes over them with no effect.
Root Cause
Three architectural factors:
Separate storage — Shapes and strokes are stored in different CRDT collections (
doc.addShape()vsdoc.addStroke()).eraseAlongSegment()inTurtleDrawing.ts:132only queriesdoc.getStrokes(), neverdoc.getShapes().Incompatible geometry —
lineIntersectsStroke()inturtleEraseUtils.tsperforms segment-to-segment hit-testing against a stroke's point array. Shapes don't have point arrays — they have type/width/height/position, requiring different intersection logic.Whole-object removal — The current erase model removes entire strokes that intersect the erase path. It does not split, clip, or carve. This means even if shapes were included, erasing "through" a rectangle would delete the entire rectangle, not cut a hole in it.
Relevant Files
src/turtle/TurtleExecutor.ts— Lines 330-351 (erase dispatch), 358-406 (shape creation, ignores pen mode)src/turtle/TurtleDrawing.ts— Lines 132-168 (eraseAlongSegment, only checks strokes)src/turtle/turtleEraseUtils.ts—lineIntersectsStroke()(segment-based hit-testing)src/crdt/DrawfinityDoc.ts—addShape()/removeShape()(separate from stroke storage)Proposed Fix (Two Tiers)
Tier 1: Erase deletes whole shapes (easy)
Add shape hit-testing to
eraseAlongSegment():doc.getShapes()alongsidedoc.getStrokes()doc.removeShape()for intersecting shapesTier 2: Pixel-level carving (hard)
Allow erasing to cut holes in shapes (e.g., carve a smiley face into a circle):
Workaround
Scripts can simulate carving by overdrawing shapes with the canvas background color instead of using erase mode. See the "Smiley Face" example in
docs/turtle-scripts-pending.md.🤖 Generated with Claude Code