Editor has no 'handle size' preference — small handles for fine work, large handles for fast interaction; the editor's node handles are a fixed size #323

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

Finding

grep -rn 'handleSize\|nodeRadius' src/components/editor/ returns 0 hits for a user-preference. The node handles (the circles drawn at each node) are a fixed size.

A user with:

  • 200 nodes in a complex design
  • Wants small handles (4px) to see the path clearly
  • Or: 5 nodes in a simple design
  • Wants large handles (12px) to easily click them

Currently: fixed at some value (likely 6-8px).

The fix is a user preference for handle size.

Where

  • canvasRenderer: src/components/editor/canvasRenderer.ts (where handles are drawn)
  • No size preference: grep -rn 'handleSize' src/components/editor/ returns 0
  • Settings: SettingsModal (per #306) is where preferences live

Suggested fix shape

  1. Type: add handleSize: number to a user preferences type (or in SnapSettings).

  2. UI: a "Handle size" select in the editor's settings (or in the snap settings):

<SelectField
  label="Handle size"
  value={handleSize}
  options={[
    { value: '4', label: 'Small (4px)' },
    { value: '6', label: 'Medium (6px)' },
    { value: '10', label: 'Large (10px)' },
    { value: '14', label: 'Extra large (14px)' },
  ]}
  onChange={(v) => setHandleSize(Number(v))}
/>
  1. Render: in canvasRenderer, use the preference:
const nodeRadius = handleSize / 2;
ctx.arc(n.x, n.y, nodeRadius, 0, Math.PI * 2);
  1. Persistence: the preference is stored in localStorage (per the pattern of other user prefs).

  2. Use cases: tablet/trackpad users (large), precision digitizers (small), screen-reader users (large for visibility).

Severity

Low. The user can zoom. Power users notice.

Discovered by

Gap analysis (2026-10-02) of editor preferences.

  • The grid size (per #288) is a related preference.
  • The snap settings (per SnapSettings) are the parallel family.
  • Figma has cursor and handle size preferences. The editor's gap is the parallel.
## Finding `grep -rn 'handleSize\|nodeRadius' src/components/editor/` returns 0 hits for a user-preference. The node handles (the circles drawn at each node) are a fixed size. A user with: - 200 nodes in a complex design - Wants small handles (4px) to see the path clearly - Or: 5 nodes in a simple design - Wants large handles (12px) to easily click them Currently: fixed at some value (likely 6-8px). The fix is a user preference for handle size. ## Where - canvasRenderer: `src/components/editor/canvasRenderer.ts` (where handles are drawn) - No size preference: `grep -rn 'handleSize' src/components/editor/` returns 0 - Settings: SettingsModal (per #306) is where preferences live ## Suggested fix shape 1. **Type**: add `handleSize: number` to a user preferences type (or in SnapSettings). 2. **UI**: a "Handle size" select in the editor's settings (or in the snap settings): ```tsx <SelectField label="Handle size" value={handleSize} options={[ { value: '4', label: 'Small (4px)' }, { value: '6', label: 'Medium (6px)' }, { value: '10', label: 'Large (10px)' }, { value: '14', label: 'Extra large (14px)' }, ]} onChange={(v) => setHandleSize(Number(v))} /> ``` 3. **Render**: in canvasRenderer, use the preference: ```ts const nodeRadius = handleSize / 2; ctx.arc(n.x, n.y, nodeRadius, 0, Math.PI * 2); ``` 4. **Persistence**: the preference is stored in localStorage (per the pattern of other user prefs). 5. **Use cases**: tablet/trackpad users (large), precision digitizers (small), screen-reader users (large for visibility). ## Severity Low. The user can zoom. Power users notice. ## Discovered by Gap analysis (2026-10-02) of editor preferences. ## Related - The grid size (per #288) is a related preference. - The snap settings (per SnapSettings) are the parallel family. - Figma has cursor and handle size preferences. The editor's gap is the parallel.
Author
Owner

Closed by commit cda10c0 on origin/main.

A user with 200 nodes in a dense design wanted smaller handles (4px) so
the path underneath stayed readable. A user on a tablet / trackpad with 5
nodes wanted bigger handles (10-14px) so they could hit them accurately.
The size was hard-coded as Math.max(3, (hovered ? 8 : 6) * scale * 0.5);
the right-panel had no UI for it.

Ship a "Handle Size" slider in the right-panel Snap Settings (4-14px,
default 6 — matches the pre-#323 look). drawPath reads the new
handleSize option and uses it instead of the hard-coded 6/8. Hover
bumps by +2 so the highlight stays readable at all settings. The
Math.max(3, ...) floor still applies so zoomed-out nodes stay visible.

Wiring:

  • SnapSettings gains optional nodeHandleSize?: number (back-compat for
    older persisted state without the field reads as 6).
  • DEFAULT_SNAP_SETTINGS now sets nodeHandleSize: 6.
  • EditorCanvas forwards snapSettings.nodeHandleSize ?? 6 to drawPath.
  • EditorRightPanel renders a Slider (4..14, step 1) under "Show
    Coordinates"; the label updates live ("Handle Size: 10px").

Tests: 7 new canvasRenderer cases (default, 4/10/14, hover +2, symmetric
nodes, zoomed-out floor) + 7 new issue-323 cases (label renders, default
6, controlled-input reflection, slider role, keyboard arrow forwards
value, back-compat). All 778 editor tests pass; tsc + eslint clean.

Closed by commit cda10c0 on origin/main. A user with 200 nodes in a dense design wanted smaller handles (4px) so the path underneath stayed readable. A user on a tablet / trackpad with 5 nodes wanted bigger handles (10-14px) so they could hit them accurately. The size was hard-coded as Math.max(3, (hovered ? 8 : 6) * scale * 0.5); the right-panel had no UI for it. Ship a "Handle Size" slider in the right-panel Snap Settings (4-14px, default 6 — matches the pre-#323 look). drawPath reads the new `handleSize` option and uses it instead of the hard-coded 6/8. Hover bumps by +2 so the highlight stays readable at all settings. The Math.max(3, ...) floor still applies so zoomed-out nodes stay visible. Wiring: - SnapSettings gains optional `nodeHandleSize?: number` (back-compat for older persisted state without the field reads as 6). - DEFAULT_SNAP_SETTINGS now sets `nodeHandleSize: 6`. - EditorCanvas forwards `snapSettings.nodeHandleSize ?? 6` to drawPath. - EditorRightPanel renders a Slider (4..14, step 1) under "Show Coordinates"; the label updates live ("Handle Size: 10px"). Tests: 7 new canvasRenderer cases (default, 4/10/14, hover +2, symmetric nodes, zoomed-out floor) + 7 new issue-323 cases (label renders, default 6, controlled-input reflection, slider role, keyboard arrow forwards value, back-compat). All 778 editor tests pass; tsc + eslint clean.
Mark closed this issue 2026-10-05 01:24:00 +00:00
Sign in to join this conversation.
No description provided.