Skip to content

feat(helper-lines): custom snapping guides + edge snapping for text & paint (#833, #834)#841

Merged
hm21 merged 5 commits into
stablefrom
feat/833-834-custom-snapping-guides
Jun 27, 2026
Merged

feat(helper-lines): custom snapping guides + edge snapping for text & paint (#833, #834)#841
hm21 merged 5 commits into
stablefrom
feat/833-834-custom-snapping-guides

Conversation

@hm21

@hm21 hm21 commented Jun 27, 2026

Copy link
Copy Markdown
Owner

Implements #833 and #834.

#834 — App-defined custom snapping guide lines

Adds an API for apps to define their own snapping/helper guides (safe areas, thirds, columns, layout slots, …):

ProImageEditorConfigs(
  helperLines: HelperLineConfigs(
    customGuides: [
      HelperGuideLine(
        axis: Axis.vertical,
        position: 1 / 3,
        positionMode: HelperGuidePositionMode.normalized,
      ),
      HelperGuideLine(axis: Axis.horizontal, position: 120), // absolute px
    ],
    style: HelperLineStyle(customGuideColor: Color(0xFF00BFA5)),
  ),
)
  • HelperGuideLineaxis (vertical snaps X, horizontal snaps Y), position, and positionMode (absolute editor-body pixels or normalized 0.01.0).
  • Custom guides participate in layer snapping (reusing releaseThreshold) and are drawn with the new HelperLineStyle.customGuideColor while a layer snaps to them — even when showLayerAlignLine is false.
  • Resolved against the live editor-body size, so snapping stays consistent across resizes (the snap always lands on the drawn line).
  • New Custom-Guide-Lines example (thirds + safe-area guides).

#833 — Text & paint snap by their edges

Text and paint layers now expose their left / center / right and top / center / bottom edges as snap anchors (no dependence on TextAlign). When aligning to another layer or a custom guide, whichever edge sits closest snaps to it, making it easy to align text/paint blocks by their visible edge. Other layer types keep their single configured anchor; the editor center line still snaps by the layer center.

Implementation notes

  • LayerInteractionManager._updateAlignmentGuides was generalized to multiple active-layer anchors (text/paint edges, both axes) and multiple targets (other layers' anchors + custom guides), keeping the existing snap/release hysteresis. A isVerticalGuideCustom/isHorizontalGuideCustom flag selects the draw color.
  • Layer.renderSize exposes the rendered (already-scaled) content size used to derive edge anchors; calculateMovement receives editorBodySize to resolve custom-guide positions into the editor's center-relative coordinate space.

Tests

Added unit tests for HelperGuideLine.resolvePosition (absolute/normalized) and equality. Full suite (436 tests) passes and dart analyze is clean for both the package and the example.

…#834)

Custom guides (#834):
- Add HelperGuideLine (axis + absolute/normalized position) and
  HelperLineConfigs.customGuides. Custom guides participate in layer
  snapping and are drawn (HelperLineStyle.customGuideColor) while a layer
  snaps to them, even when showLayerAlignLine is disabled.
- Add a "Custom-Guide-Lines" example demonstrating thirds and safe-area
  guides.

Text edge snapping (#833):
- Text layers now expose their left, center and right edges as snap
  anchors; the edge closest to a guide (editor center, another layer or a
  custom guide) snaps to it. Other layer types keep their single anchor.

Implementation:
- Generalize the layer-align/center-line snapping in LayerInteractionManager
  to multi-anchor (text) and multi-target (layers + custom guides), reusing
  the existing release/threshold hysteresis.
- Add Layer.renderSize to derive text edge anchors and pass editorBodySize
  into calculateMovement to resolve custom guide positions.
@hm21 hm21 marked this pull request as draft June 27, 2026 15:48
- Fix text "jumping straight to the center line": the editor center line
  again snaps by the layer center (single anchor), so onScaleStart and the
  center-line path stay consistent. Edge snapping now happens only via the
  layer-align / custom-guide path, which has proper per-target hysteresis.
- Extend edge snapping to paint layers in addition to text.
- Add top/center/bottom (vertical) edges for both text and paint, alongside
  left/center/right.
- Fix wrong snap points after a resize: `renderSize` already reflects the
  on-screen (scaled) size, so it must not be multiplied by `scale` again -
  the double-count grew with `scale`, which changes on resize.
@hm21 hm21 changed the title feat(helper-lines): custom snapping guides + text edge snapping (#833, #834) feat(helper-lines): custom snapping guides + edge snapping for text & paint (#833, #834) Jun 27, 2026
hm21 added 3 commits June 27, 2026 18:19
…r guide

- The editor center lines snap by every edge of text/paint layers again
  (closest edge wins), not just the layer center. The earlier jump is fixed
  properly by initializing the snap hysteresis in onScaleStart from the same
  closest edge that calculateMovement evaluates.
- Allow every edge to snap to the same layer/custom guide: the align snap
  helper de-duped by target only, which blocked the other edges once one had
  snapped. The hysteresis key now also encodes the snapping edge.
…itches

With multi-anchor edge snapping, the edge closest to a center line switches
at the midpoint between two edges (e.g. left -> center). The tracked position
then flips sign discontinuously, which the crossing-based center-line snap
misread as a real crossing and snapped to the center in one jump.

Track the closest edge between move frames and suppress a *new* center-line
snap on the frame the closest edge switches, so only a genuine crossing snaps.
Dragging now stops smoothly at each edge instead of jumping.
Edge anchors used the unrotated half-size (center +/- width/2), so a rotated
layer's snap lines no longer lined up with its actual extent. Derive the edges
from the rotated axis-aligned bounding box (W*|cos| + H*|sin|), which collapses
to the unrotated size when the layer is not rotated.
@hm21 hm21 self-assigned this Jun 27, 2026
@hm21 hm21 marked this pull request as ready for review June 27, 2026 16:38
@hm21 hm21 merged commit b91c862 into stable Jun 27, 2026
1 check passed
@hm21 hm21 deleted the feat/833-834-custom-snapping-guides branch June 27, 2026 16:39
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