feat(dial): snap to the closest altitude on drag release

A drag is a way of grabbing the altitude dial, not a free-standing encoder
detent. Until now onDialUp held the live blend wherever the knob stopped (the
"no auto-complete" model), so a grab-and-release could leave the experience
parked mid-morph between two altitudes.

Now a real turn (moved >= 6) auto-scrubs the short way to Math.round(pos) and
settles there (frac 0 locks) — a grab-and-release always lands on a discrete
altitude, exactly like a tap or label click. The tap path (moved < 6 ->
jumpToScale) is unchanged, and reduced motion is handled by autoScrub (jump to
target, no tween).

Adds an altitude-lock e2e asserting a partial drag settles on an integer
altitude after release. Full altitude-lock (14) + a11y + i18n suites green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
BenStullsBets
2026-06-30 10:50:51 -07:00
parent 00fd9aab17
commit 8e790b4a95
2 changed files with 34 additions and 2 deletions
+5 -1
View File
@@ -1076,7 +1076,11 @@ function onDialUp(e) {
}
return;
}
// No auto-complete: hold the blend wherever the knob stopped (continuous-encoder model).
// Snap on release: a drag is a way of GRABBING the dial, not a free-standing
// encoder detent — so when the operator lets go between altitudes, auto-scrub the
// short way to the CLOSEST one and settle there (frac 0 locks). The result is the
// same as a tap/label-click: a grab-and-release always lands on a discrete altitude.
autoScrub(Math.round(pos));
}
// Click a label → auto-scrub the SHORTEST signed way around the ring to that scale.