Project Where the Flick Is Going
MUST: Project the resting position from release velocity, THEN snap to the target nearest that projected point — never snap to the target nearest the release point, which cannot tell a nudge from a throw.
Use release velocity to project a resting position, then snap to the target nearest that point
const project = (v, decel = 0.998) => (v / 1000) * decel / (1 - decel);
const rest = x + project(velocityX);
snapTo(nearestTarget(rest)); // not nearestTarget(x)Bad
Good
Why it matters
A carousel that snaps to whichever slide is nearest the release point cannot tell a nudge from a throw. Both gestures end at roughly the same x, so both advance exactly one slide, and the hard flick you meant as "skip ahead" is quietly discarded. Momentum projection uses the velocity you already measured to answer a different question: not "where did the finger stop" but "where would the element come to rest if it kept moving".
Apple ships an exponential-decay projection rather than the physics-textbook v²/(2·decel) — `project(v) = (v / 1000) * d / (1 - d)` with a deceleration rate d of about 0.998 — and then picks the snap target nearest that projected endpoint. This is distinct from "Give Drag Gestures Real Physics", which uses velocity as a binary gate: above ~0.11 px/ms the sheet dismisses, below it springs back.
That rule never computes a landing point, so it can decide whether to commit but not how far to travel. Projection is what turns a small input into a big output.