Skip to main content

Search rules

Search all UI Guides rules by name, category, or source

interactionsEmil Kowalski

Give Drag Gestures Real Physics

SHOULD

SHOULD: Give drags real physics: dismiss on velocity (`Math.abs(distance) / elapsedMs > ~0.11`) rather than a distance threshold, damp past boundaries (`over * limit / (over + limit)`), call `setPointerCapture(e.pointerId)` on drag start, and ignore extra pointers once a drag owns one.

Dismiss on velocity, damp at boundaries, capture the pointer, and ignore extra touch points mid-drag

Bad

Good

Why it matters

Four mechanics turn a drag from a hit-test into something that feels like an object. Velocity dismissal: measure `Math.abs(dx) / elapsedMs` between pointer moves and dismiss above roughly 0.11 px/ms, so a quick flick works and users do not have to haul the sheet across the screen. Damping: past a natural edge, apply rising resistance (`over * limit / (over + limit)`) rather than a hard clamp — real things slow before they stop, and an invisible wall reads as a bug.

`setPointerCapture(e.pointerId)` on drag start keeps the pointer stream flowing to your element even after the pointer leaves its bounds, which is exactly what a fast flick does. And once a drag owns a pointer, bail out of further `pointerdown` handlers so a second finger cannot re-anchor the origin and teleport the element.

Built by Gleb Stroganov, design engineer at Evil Martians.

The rules come from other people's skills and guidelines — Vercel, Rauno Freiberg, @Ibelick, impeccable, Emil Kowalski, Tailwind, RAMS — each one credited on the Sources page. The work here is extraction and wiring: every rule is pulled into one corpus, given a good and a bad example you can operate, a MUST/SHOULD/NEVER rule an agent can paste, and a link back to where it came from.