Description:
Summary
Element.Shape supports an optional fillColor, but Element.Path (freehand
PEN strokes) is stroke-only — there's no way to fill a loop the user has drawn.
Add a fill color for closed paths, mirroring the Shape fill model, and
expose it through the published drawbox-ui ContextBar so it's usable from the UI.
Motivation
Filling a closed freehand region is a common, expected drawing primitive, and the
data/UI plumbing for fills already exists for shapes. Today a user drawing a
closed loop can only outline it.
Design
Two additive, back-compatible fields on Element.Path:
closed: Boolean = false — draws the closing segment (last→first) so the loop
has a continuous outline.
fillColor: Color? = null — interior fill, painted only when the path is
also closed (an open path has no well-defined interior).
closed is an explicit flag (not geometric auto-detection) for determinism,
clean round-trip/SVG (Z) mapping, and collab/LWW friendliness. Closure and
fill stay orthogonal, so a closed-but-unfilled loop is also representable.
Scope
- Model:
Element.Path.closed + Element.Path.fillColor.
- Renderer: fill pass under the stroke for closed+filled paths; closes both
the uniform and variable-width stroke geometry.
- Serialization: threads both fields; legacy JSON loads as open/unfilled.
- Domain:
SetSelectedFillColor now covers paths; new
SetSelectedPathClosed intent + DrawBoxController.setSelectionPathClosed.
- drawbox-ui:
ContextBarIntent.SetPathClosed, ContextBarState.pathClosed,
ContextBarSlots.showPath, a pathContextItems builder (open/close toggle +
fill swatch), and PathClosedIcon.
- Sample: HomeScreen treats a freehand-path selection as fillable and shows
the close/fill chips.
- SVG export: closes (
Z) and fills.
- Docs:
FEATURES.md cataloging the full menu surface.
Public API note
The frozen 2.0 surface (DrawBoxController, Mode, Intent, Event, State)
is only extended here (new optional Element.Path fields + new intents), so
it's semver-safe. The drawbox-ui ContextBar additions are likewise additive.
Acceptance criteria
Flow
Select a freehand loop → tap Close → tap Fill → pick a color → it fills.
Description:
Summary
Element.Shapesupports an optionalfillColor, butElement.Path(freehandPEN strokes) is stroke-only — there's no way to fill a loop the user has drawn.
Add a fill color for closed paths, mirroring the Shape fill model, and
expose it through the published
drawbox-uiContextBar so it's usable from the UI.Motivation
Filling a closed freehand region is a common, expected drawing primitive, and the
data/UI plumbing for fills already exists for shapes. Today a user drawing a
closed loop can only outline it.
Design
Two additive, back-compatible fields on
Element.Path:closed: Boolean = false— draws the closing segment (last→first) so the loophas a continuous outline.
fillColor: Color? = null— interior fill, painted only when the path isalso
closed(an open path has no well-defined interior).closedis an explicit flag (not geometric auto-detection) for determinism,clean round-trip/SVG (
Z) mapping, and collab/LWW friendliness. Closure andfill stay orthogonal, so a closed-but-unfilled loop is also representable.
Scope
Element.Path.closed+Element.Path.fillColor.the uniform and variable-width stroke geometry.
SetSelectedFillColornow covers paths; newSetSelectedPathClosedintent +DrawBoxController.setSelectionPathClosed.ContextBarIntent.SetPathClosed,ContextBarState.pathClosed,ContextBarSlots.showPath, apathContextItemsbuilder (open/close toggle +fill swatch), and
PathClosedIcon.the close/fill chips.
Z) and fills.FEATURES.mdcataloging the full menu surface.Public API note
The frozen 2.0 surface (
DrawBoxController,Mode,Intent,Event,State)is only extended here (new optional
Element.Pathfields + new intents), soit's semver-safe. The
drawbox-uiContextBar additions are likewise additive.Acceptance criteria
Element.Pathwith afillColorrenders filled + stroked.SetSelectedFillColor+SetSelectedPathClosedfill a selected path.Flow
Select a freehand loop → tap Close → tap Fill → pick a color → it fills.