Skip to content

feat(line): smart axis snap + quick-orientation picker#48

Merged
u8array merged 2 commits into
mainfrom
feat/line-axis-constrain
May 10, 2026
Merged

feat(line): smart axis snap + quick-orientation picker#48
u8array merged 2 commits into
mainfrom
feat/line-axis-constrain

Conversation

@u8array
Copy link
Copy Markdown
Owner

@u8array u8array commented May 10, 2026

Endpoint editing:

  • onDragMove and onDragEnd both project the cursor onto a constrained axis so the line visually stays on a rail during the drag instead of only snapping at release. Length matches the axial component of the drag (Figma / Sketch convention) rather than the diagonal Euclidean distance.
  • Default behaviour: Figma-style auto-snap to the nearest 45° step when the raw angle is within ±5°, otherwise free.
  • Shift always forces an explicit 45°-step constraint.

Quick-orientation picker in the Properties panel:

  • Four buttons (—, |, /, ) rendered as inline 12×12 SVGs for crisp, font-independent icons.
  • Buttons pick the candidate angle closest to the line's current angle so the line keeps its rough direction. Repeated click on the active orientation flips the line 180° (e.g. 0° ↔ 180°).
  • View-rotation aware: candidates are expressed as on-screen angles, then converted to label-space by subtracting the current view rotation. Clicking '—' always yields a visually horizontal line.
  • Length is preserved (no projection collapse when rotating).

Endpoint editing:
- onDragMove and onDragEnd both project the cursor onto a constrained
  axis so the line visually stays on a rail during the drag instead of
  only snapping at release. Length matches the axial component of the
  drag (Figma / Sketch convention) rather than the diagonal Euclidean
  distance.
- Default behaviour: Figma-style auto-snap to the nearest 45° step when
  the raw angle is within ±5°, otherwise free.
- Shift always forces an explicit 45°-step constraint.

Quick-orientation picker in the Properties panel:
- Four buttons (—, |, /, \) rendered as inline 12×12 SVGs for crisp,
  font-independent icons.
- Buttons pick the candidate angle closest to the line's current angle
  so the line keeps its rough direction. Repeated click on the active
  orientation flips the line 180° (e.g. 0° ↔ 180°).
- View-rotation aware: candidates are expressed as on-screen angles,
  then converted to label-space by subtracting the current view
  rotation. Clicking '—' always yields a visually horizontal line.
- Length is preserved (no projection collapse when rotating).
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a centralized line constraint system with free, shift, and auto-snap modes, refactoring the LineObject component to use a new projection utility. It also adds an orientation picker to the line properties panel that remains accurate under canvas rotation and includes updated translations for multiple locales. Feedback suggests enhancing the orientation picker's toggle logic by using angular distance instead of strict equality to prevent issues with angle normalization.

Comment thread src/registry/line.tsx Outdated
Reviewer-spotted (gemini-code-assist on PR #48): with strict ===, an angle
entered as -270° in the NumberInput would not match candidate 90° even
though they are the same orientation, so the second-click flip would
silently fall through to the nearest-pick branch.

Use angleDistance with a 0.5° tolerance for the match check; preserve
the existing <= tie-breaking on the nearest-pick fall-through so the
already-pinned 'tie → first candidate' behaviour stays.
@u8array u8array merged commit 85918eb into main May 10, 2026
2 checks passed
@u8array u8array deleted the feat/line-axis-constrain branch May 10, 2026 14:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant