openpencil/src/components
TKman 6651d88b87 fix(vector): render dashPattern strokes correctly on closed crescents
Vector nodes with stroke.dashPattern were rendering as solid lines, and
even when the dash was applied through brute outline-stroke conversion,
closed crescent shapes (e.g. annular wedges) showed two parallel dashed
arcs instead of a single arc along the centerline.

Root cause:

- drawVectorPathStrokes converted stroke to a fill outline before drawing,
  leaving no place for PathEffect.MakeDash to apply.
- A closed crescent is a single closed path traced around both the outer
  and inner arcs, so dashing the path produces two visible arcs.

Fix:

- packages/core/src/canvas/scene.ts: in drawVectorPathStrokes, when the
  stroke has a dashPattern, skip the outline conversion and draw with
  strokePaint + PathEffect.MakeDash directly. In renderShapeUncached,
  dashed VECTOR nodes with a vectorNetwork now route through a new
  centerline path instead of the precomputed strokeGeometry.
- packages/core/src/vector/index.ts: new vectorNetworkToCenterlinePath.
  For closed thin crescents (cycle of even length where pairwise opposite
  vertex distance is small relative to perimeter and consistent), detect
  the two cap segments via vertex direction-change angles, split the
  cycle into outer/inner subchains, pair vertices by angle, and emit a
  smooth Path.addArc when the midpoints fit a circle (fitCircleArc with
  3-point construction + radius tolerance), falling back to a midpoint
  polyline otherwise. Open paths use the existing chain walk.

JSX prop wiring so users can author dashed Vectors:

- packages/core/src/design-jsx/tree.ts: add strokeDash?: number[] | boolean.
- packages/core/src/design-jsx/renderer.ts: applyStrokeOverrides reads
  strokeDash and writes Stroke.dashPattern; true expands to [w*2, w*2].
- packages/core/src/io/formats/jsx/export.ts: solidStroke serializes
  dashPattern back to strokeDash on JSX export.

Editor UI:

- src/components/properties/StrokeSection.vue: dash toggle button plus
  ScrubInputs for dash and gap length, writing strokes[0].dashPattern.

bun run check passes. Pre-existing test failures (drop shadow / auto
layout) are unrelated to this change and reproduce on a clean
upstream/master.
2026-05-03 22:44:42 +03:00
..
chat Refactor architecture boundaries across core, app, and packages (#234) 2026-04-30 15:14:19 +03:00
CollabPanel fix(app): theme remaining ui color tokens 2026-04-30 16:26:17 +03:00
ColorPicker Refactor architecture boundaries across core, app, and packages (#234) 2026-04-30 15:14:19 +03:00
ColorPickerPanel fix(app): use theme warning colors 2026-04-30 16:18:43 +03:00
MobileHud Refactor architecture boundaries across core, app, and packages (#234) 2026-04-30 15:14:19 +03:00
properties fix(vector): render dashPattern strokes correctly on closed crescents 2026-05-03 22:44:42 +03:00
Toolbar Refactor architecture boundaries across core, app, and packages (#234) 2026-04-30 15:14:19 +03:00
ui fix(app): theme remaining ui color tokens 2026-04-30 16:26:17 +03:00
AppMenu.vue Refactor architecture boundaries across core, app, and packages (#234) 2026-04-30 15:14:19 +03:00
AppToast.vue feat(tauri): add signed updater 2026-05-01 13:00:50 +03:00
CanvasMenu.vue Refactor architecture boundaries across core, app, and packages (#234) 2026-04-30 15:14:19 +03:00
ChatPanel.vue Refactor architecture boundaries across core, app, and packages (#234) 2026-04-30 15:14:19 +03:00
CodePanel.vue fix(app): theme remaining ui color tokens 2026-04-30 16:26:17 +03:00
DesignPanel.vue Refactor architecture boundaries across core, app, and packages (#234) 2026-04-30 15:14:19 +03:00
EditorCanvas.vue Refactor architecture boundaries across core, app, and packages (#234) 2026-04-30 15:14:19 +03:00
FillPicker.vue feat(app): add color variable binding picker 2026-05-01 17:11:50 +03:00
FontPicker.vue Refactor architecture boundaries across core, app, and packages (#234) 2026-04-30 15:14:19 +03:00
GradientEditor.vue Refactor architecture boundaries across core, app, and packages (#234) 2026-04-30 15:14:19 +03:00
ImageFillPicker.vue Refactor architecture boundaries across core, app, and packages (#234) 2026-04-30 15:14:19 +03:00
LayersPanel.vue Translate visible panel chrome for Russian locale 2026-03-25 18:12:09 +03:00
LayerTree.vue Refactor architecture boundaries across core, app, and packages (#234) 2026-04-30 15:14:19 +03:00
MobileDrawer.vue Refactor architecture boundaries across core, app, and packages (#234) 2026-04-30 15:14:19 +03:00
PagesPanel.vue Fix inline rename and rotated hit testing 2026-03-31 16:44:35 +03:00
PickerSlider.vue Format 2026-04-06 14:40:19 +03:00
PropertiesPanel.vue Refactor architecture boundaries across core, app, and packages (#234) 2026-04-30 15:14:19 +03:00
SafariBanner.vue chore: format sources with oxfmt 2026-05-03 21:03:40 +03:00
ScrubInput.vue feat(app): bind size fields to variables 2026-05-01 17:20:45 +03:00
TabBar.vue feat(app): add light theme setting 2026-04-30 15:52:59 +03:00
VariablesDialog.vue Refactor architecture boundaries across core, app, and packages (#234) 2026-04-30 15:14:19 +03:00
ZoomDropdown.vue Refactor architecture boundaries across core, app, and packages (#234) 2026-04-30 15:14:19 +03:00