Engineering Journal
Schema Editor
Schema Editor

Snap to Nearest Point Is Not Snap to Alignment. Most Editors Implement the Wrong One.

2026-06-04

TLDR

"Snap to nearest" and "snap to alignment" are different algorithms. Nearest-point snap (Euclidean distance) finds one winner. Alignment snap (per-axis distance) finds two independent winners. Most editor snap implementations are nearest-point snap. Most users want alignment snap. The mismatch is why users still reach for the coordinate panel after snapping.


What the Industry Does

The dominant snap algorithm in tutorials, open-source editors, and many commercial tools computes Euclidean distance from the cursor to all candidate points and snaps to the nearest. This is nearest-point snap. It aligns to the single closest thing.

Figma's smart guides and Adobe XD's layout snap are alignment snap: they show separate horizontal and vertical alignment lines and snap each axis independently. This is not the same algorithm. It is the correct algorithm for layout.

Most editors that are not Figma or XD implement nearest-point snap and call it alignment snap.

Why It Fails for This Problem Class

Users laying out diagrams do not think in terms of "the closest element." They think in terms of "align this to A's right edge" and "align this to B's top edge." These are two constraints, not one. They may involve two different elements. A single nearest-point algorithm cannot satisfy two constraints from two elements simultaneously.

The practical consequence: users snap to one element, note the aligned position, then need to correct the other axis manually. The snap feature only helps with one degree of freedom at a time. For operations that require alignment in both axes, snap and manual coordinate entry are used in combination.

This is the symptom that identifies the wrong algorithm: users who use snap frequently but also frequently enter coordinates manually. The manual coordinates are for the axis the snap algorithm cannot align.

The Better Approach

Run independent nearest-candidate searches for X and Y:

// Each axis finds its own best candidate
let bestX = x, bestY = y;
let minDx = threshold, minDy = threshold;

candidates.forEach(bb => { [bb.x, bb.cx, bb.right].forEach(cx => { const d = Math.abs(x - cx); if (d < minDx) { minDx = d; bestX = cx; } }); [bb.y, bb.cy, bb.bottom].forEach(cy => { const d = Math.abs(y - cy); if (d < minDy) { minDy = d; bestY = cy; } }); });

This is not significantly harder than nearest-point snap. The loop is the same. The distance function changes from Math.hypot to two Math.abs calls. The result changes from one winner to two independent winners.

What You Give Up

Axis-independent snap can produce unintuitive combinations. If the nearest X candidate is the left edge of element A and the nearest Y candidate is the bottom edge of element C (which is across the canvas), the element snaps to a position that aligns to neither A nor C as a whole. The snap point is geometrically correct but visually confusing.

Visual alignment guides (lines drawn from the snapped element to the reference edges) are essential for axis-independent snap. Without guides, the user cannot tell which elements they snapped to. With guides, the two-axis alignment is explicit and the result is predictable.

When the Common Pattern Is Right

Nearest-point snap is correct for snapping to exact positions: snapping a wire endpoint to a component pin, snapping a shape to a grid intersection, snapping a vertex to another vertex. In these cases you want the whole point, not independent axes. For layout alignment, where the goal is edge-to-edge or center-to-center across multiple reference elements, axis-independent snap is the right algorithm.

Read this post in the full Engineering Journal →