Skip to content

feat(canvas): smart-align guides during line endpoint resize#50

Merged
u8array merged 2 commits into
mainfrom
feat/line-resize-snap-guides
May 10, 2026
Merged

feat(canvas): smart-align guides during line endpoint resize#50
u8array merged 2 commits into
mainfrom
feat/line-resize-snap-guides

Conversation

@u8array
Copy link
Copy Markdown
Owner

@u8array u8array commented May 10, 2026

No description provided.

Line endpoint resize previously bypassed Konva's Transformer (it uses
custom <Rect> handles in LineObject), so the Stage-level object-snap
that fires for normal drag never kicked in — endpoints could only
free-form-snap to the grid.

Plumb getOthersSnapshot / labelRect / setGuides through KonvaObjectProps
so LineObject can run its own snap during endpoint drag:

- snapEndpoint(): zero-size rect snap via computeSnap against neighbour
  edges + label rect, in stage coords. Local↔stage conversion via the
  parent group's absoluteTransform keeps the snap correct under rotated
  view (viewRotation 90°/270°). Snap is skipped when Shift is held
  (axis constraint wins) and when grid-snap is on (mutual exclusion
  with the existing drag-time snap, mirroring the rest of the app).
- snapshot is cached at drag-start to avoid re-querying every other
  node's clientRect per frame; cleared on drag-end.
- selectionHandlers helper applied to BarcodeObject's remaining unfixed
  Group node (caught while threading new KonvaObjectProps imports).

Open trade-off: snap picks the nearest neighbour edge by raw distance.
For aligning a line endpoint to the *matching* edge of another line
(bottom-to-bottom etc.) the user may need to drag past the near edge.
A side-aware heuristic (which edge to prefer when dragging in a given
direction) is a follow-up — orthogonal to this branch's scope.
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 implements object-snapping for line endpoints, allowing lines to snap to the edges of other shapes and labels during resizing. It introduces new hooks in the KonvaObjectProps interface and a snap-guide pipeline in LineObject.tsx that handles coordinate conversions for rotated views. Feedback was provided regarding a performance optimization in LabelCanvas.tsx, where defining getOthersSnapshot inside a loop causes unnecessary function re-creations on every render.

Comment thread src/components/Canvas/LabelCanvas.tsx Outdated
Reviewer-spotted (gemini-code-assist on PR #50): defining the snapshot
closure inside objects.map allocated a fresh function for every object
on every LabelCanvas render — and LabelCanvas re-renders on every
setGuides call during a drag.

Lift to a single useCallback-stable function that takes excludeId. The
KonvaObjectProps signature changes from () => SnapRect[] to
(excludeId) => SnapRect[]; LineObject's lazy snapshot call now passes
obj.id.
@u8array u8array merged commit 531f5e6 into main May 10, 2026
2 checks passed
@u8array u8array deleted the feat/line-resize-snap-guides branch May 10, 2026 19:50
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