FIG-001/ GESTURE

swipe to decide.

A Tinder-style card stack — drag horizontally, watch the top card translate AND rotate (one source MotionValue drives both via useTransform), and a LIKE / NOPE badge fades in on the relevant side. Release past the 140px distance threshold OR with > 650 px/s velocity flings the card off screen and the stack springs forward. Anything weaker snaps back.

  • One useMotionValue for the top card's horizontal offset, three useTransforms on top of it: rotation maps [-200, 0, 200][-18°, 0°, 18°], and the LIKE / NOPE badge opacities ramp in over the 40–140px gutter. One source, four visuals, can't desync.
  • The commit gate is distance OR velocity: 140px past origin or > 650 px/s in either direction fires the fly-off. The direction is taken from Math.sign(info.offset.x) with info.velocity.x as the fallback for fast flicks with sub-threshold distance.
  • The stack uses three card slots with hard-coded depth (Y offset + scale on the back ones — no actual 3D). On commit, the top card animates to ±600px via a soft spring, then deck = deck.slice(1) drops it and the {#each} block re-keys the remaining cards forward.
↩ all examples
pattern · swipe-card stack mode · live running source
NOPE

Ada

designs algorithms in her sleep

← nope · like →

Grace

Linus

category · gesture
sheet · sheet 01 / 02
⟳ to re-run
FIG-002/ GESTURE

flick to dismiss.

A bottom sheet that follows your finger as you pull it down. Past 120px OR with downward velocity > 700 px/s, it commits to dismiss. Otherwise it springs back. pan gives you offset + velocity; you decide what to do with them.

  • onPan fires every frame with info.offset and info.velocity. We clamp offset to >= 0 so the sheet only follows downward drags, and write it straight into a motion value the transform reads.
  • The release decision in onPanEnd is the distance OR velocity pattern: pulled more than 120px past origin or still moving downward faster than 700px/s ⇒ dismiss. Either condition alone fires the close. This is how a real sheet feels — slow pull works, fast flick also works.
  • The overlay opacity is a useTransform of the same sheet offset — at 0px it's fully opaque, at 300px it's transparent. One source value drives both the sheet position and the dimmer, so the visuals can't desync.
↩ all examples
pattern · swipe-to-dismiss sheet mode · live running source
category · gesture
sheet · sheet 02 / 02
⟳ to re-run