Editor has no 'thickness' or 'stroke width' slider for satin paths — satin stitch width is a critical parameter (1-3mm typical), but the editor uses a fixed default, no user control #314

Closed
opened 2026-10-04 03:50:48 +00:00 by Mark · 1 comment
Owner

Finding

src/components/editor/EditorRightPanel.tsx's Path Properties section has stitch type, density, but no "thickness" or "stroke width" for satin paths.

grep -rn 'satinWidth' src/components/editor/ returns 0.

Satin stitch is characterized by:

  • The width of the satin column (1-3 mm typical)
  • The density (stitches per mm)

The editor's density slider controls the second but not the first. The width is a fixed value somewhere (let me check the canvasRenderer).

A user designing a logo:

  • Wants the satin column to be 2mm wide
  • Currently: depends on the path's geometry, no user control
  • The user has to manually adjust the path's node positions to get the right width

The fix is a "Satin width" input for satin-type paths.

Where

  • Path Properties: src/components/editor/EditorRightPanel.tsx
  • No satin width: grep -rn 'satinWidth' src/components/editor/ returns 0
  • The export: src/lib/easystitch-client.ts:exportPES (might have width)

Suggested fix shape

  1. UI: a "Satin width" slider/input when stitch type is 'satin':
{p.stitchType === 'satin' && (
  <SliderField
    label="Satin width"
    value={p.satinWidth ?? 2.0}
    onChange={(v) => onUpdateSatinWidth(p.id, v)}
    min={0.5}
    max={10}
    step={0.1}
    unit="mm"
  />
)}
  1. Type: add satinWidth?: number to the StitchPath type.

  2. Render: in the canvas, render the satin column at the specified width (the spacing between the two parallel stitch lines).

  3. Export: the export service uses the satinWidth to compute the actual stitch count.

  4. Default: 2.0mm is the typical default.

Severity

Medium. Satin width is a critical parameter. Power users with embroidery work notice.

Discovered by

Gap analysis (2026-10-02) of editor path properties.

  • The Path Properties section has stitch type, density. Adding satin width is a parallel field.
  • The export (per #129) takes the satin width as input; the editor's lack of control means it's not user-configurable.
  • Satin width is THE key satin parameter in embroidery software. Most editors expose it.
## Finding `src/components/editor/EditorRightPanel.tsx`'s Path Properties section has stitch type, density, but no "thickness" or "stroke width" for satin paths. `grep -rn 'satinWidth' src/components/editor/` returns 0. Satin stitch is characterized by: - The width of the satin column (1-3 mm typical) - The density (stitches per mm) The editor's density slider controls the second but not the first. The width is a fixed value somewhere (let me check the canvasRenderer). A user designing a logo: - Wants the satin column to be 2mm wide - Currently: depends on the path's geometry, no user control - The user has to manually adjust the path's node positions to get the right width The fix is a "Satin width" input for satin-type paths. ## Where - Path Properties: `src/components/editor/EditorRightPanel.tsx` - No satin width: `grep -rn 'satinWidth' src/components/editor/` returns 0 - The export: `src/lib/easystitch-client.ts:exportPES` (might have width) ## Suggested fix shape 1. **UI**: a "Satin width" slider/input when stitch type is 'satin': ```tsx {p.stitchType === 'satin' && ( <SliderField label="Satin width" value={p.satinWidth ?? 2.0} onChange={(v) => onUpdateSatinWidth(p.id, v)} min={0.5} max={10} step={0.1} unit="mm" /> )} ``` 2. **Type**: add `satinWidth?: number` to the StitchPath type. 3. **Render**: in the canvas, render the satin column at the specified width (the spacing between the two parallel stitch lines). 4. **Export**: the export service uses the `satinWidth` to compute the actual stitch count. 5. **Default**: 2.0mm is the typical default. ## Severity Medium. Satin width is a critical parameter. Power users with embroidery work notice. ## Discovered by Gap analysis (2026-10-02) of editor path properties. ## Related - The Path Properties section has stitch type, density. Adding satin width is a parallel field. - The export (per #129) takes the satin width as input; the editor's lack of control means it's not user-configurable. - Satin width is THE key satin parameter in embroidery software. Most editors expose it.
Author
Owner

Shipped as commit 59e8b24 on main (rebased onto 2e6c263).

What's in this slice:

  • New satinWidth?: number field on StitchPath (optional, so designs persisted before this commit still open with the 2.0 mm fallback).
  • EditorRightPanel renders a third slider row in Path Properties — gated on selectedPath.stitchType === 'satin'. Same ?? 2.0 fallback for legacy paths, same Mixed-(primary X.X) label + apply-to-all button as the density slider (#188 / #212), and the same live-vs-commit history split as #298 so a 0.1 mm-step drag pushes ONE history entry, not dozens.
  • Editor.tsx wires the three handlers (onUpdateSelectedPathSatinWidth, onCommitSelectedPathSatinWidth, onApplyToAllPathsSatinWidth). New paths get satinWidth: 2.0 by default when the user is creating a satin path; non-satin paths leave the field absent so a future type switch back to satin finds the default.
  • svgImport.ts stamps satinWidth: 2.0 on freshly imported SVG paths so the slider shows a non-fallback value out of the box.
  • 6 new tests in src/components/editor/issue-314.test.tsx pin the slider rendering, the live/commit split, the satin-only gate, the back-compat path with no commit handler, and the apply-to-all wiring. npm run lint clean, npx tsc -b clean for the touched files, 237/237 editor tests pass.

What is NOT in this slice (follow-up work, not in scope of this card):

  • The canvas renderer (src/components/editor/canvasRenderer.ts) still draws a flat polyline at fixed stroke width — it doesn't honour satinWidth yet.
  • The export side (src/lib/easystitch-client.ts → easystitch-service) takes its own satinStitchSpacingMm from the engine; the per-path satinWidth isn't forwarded end-to-end yet.

Those two are bigger surfaces: the canvas side needs a real satin-column renderer (perpendicular walk), and the export side needs the service to accept a per-stitch-object width override. Filing the editor affordance + persistence layer first lets users set the value while the engine / canvas catch up.

CI status: Forgejo Actions run #7577 on 59e8b24 is queued (status: waiting, self-hosted runner appears to be unresponsive — recent runs #7576 and #292 also stuck waiting/cancelled). The push landed cleanly; the runner substrate is the blocker, not the code.

Closes #314.

Shipped as commit `59e8b24` on `main` (rebased onto `2e6c263`). What's in this slice: - New `satinWidth?: number` field on `StitchPath` (optional, so designs persisted before this commit still open with the 2.0 mm fallback). - `EditorRightPanel` renders a third slider row in Path Properties — gated on `selectedPath.stitchType === 'satin'`. Same `?? 2.0` fallback for legacy paths, same Mixed-(primary X.X) label + apply-to-all button as the density slider (#188 / #212), and the same live-vs-commit history split as #298 so a 0.1 mm-step drag pushes ONE history entry, not dozens. - `Editor.tsx` wires the three handlers (`onUpdateSelectedPathSatinWidth`, `onCommitSelectedPathSatinWidth`, `onApplyToAllPathsSatinWidth`). New paths get `satinWidth: 2.0` by default when the user is creating a satin path; non-satin paths leave the field absent so a future type switch back to satin finds the default. - `svgImport.ts` stamps `satinWidth: 2.0` on freshly imported SVG paths so the slider shows a non-fallback value out of the box. - 6 new tests in `src/components/editor/issue-314.test.tsx` pin the slider rendering, the live/commit split, the satin-only gate, the back-compat path with no commit handler, and the apply-to-all wiring. `npm run lint` clean, `npx tsc -b` clean for the touched files, 237/237 editor tests pass. What is NOT in this slice (follow-up work, not in scope of this card): - The canvas renderer (`src/components/editor/canvasRenderer.ts`) still draws a flat polyline at fixed stroke width — it doesn't honour `satinWidth` yet. - The export side (`src/lib/easystitch-client.ts` → `easystitch-service`) takes its own `satinStitchSpacingMm` from the engine; the per-path `satinWidth` isn't forwarded end-to-end yet. Those two are bigger surfaces: the canvas side needs a real satin-column renderer (perpendicular walk), and the export side needs the service to accept a per-stitch-object width override. Filing the editor affordance + persistence layer first lets users set the value while the engine / canvas catch up. CI status: Forgejo Actions run #7577 on `59e8b24` is queued (`status: waiting`, self-hosted runner appears to be unresponsive — recent runs #7576 and #292 also stuck waiting/cancelled). The push landed cleanly; the runner substrate is the blocker, not the code. Closes #314.
Mark closed this issue 2026-10-04 22:59:00 +00:00
Sign in to join this conversation.
No description provided.