Skip to content

Inertia

Inertia gives pan gestures a natural momentum feel — after the user releases their finger or mouse, the canvas continues to glide and gradually decelerates. Enabled by default.

// Inertia works out of the box (friction: 0.92)
const { view } = useZoomPinch({ containerRef })

After a fast drag-and-release, the view continues moving with exponential decay. The velocity is smoothed over the last few pointer move events to avoid sudden jumps.

useZoomPinch({
containerRef,
inertia: {
friction: 0.85, // lower = more friction = stops faster
},
})
PropertyTypeDefaultDescription
enabledbooleantrueEnable/disable inertia
frictionnumber0.92Decay factor per frame (0-1)

The friction value is multiplied against the velocity on each animation frame (~60fps):

FrictionFeelUse case
0.98Very slipperyLarge canvases, map-like feel
0.95Smooth glideImage viewers
0.92Natural (default)General purpose
0.85Quick stopPrecision interfaces
0.7Very heavyWhen you want minimal drift
// Option 1: pass false
useZoomPinch({ containerRef, inertia: false })
// Option 2: enabled flag
useZoomPinch({ containerRef, inertia: { enabled: false } })
  1. During a drag, the hook tracks pointer velocity using exponential smoothing (weighted average of recent movements).
  2. On pointerup, if the velocity is above a minimum threshold (0.5 px/frame), an animation frame loop starts.
  3. Each frame: velocity *= friction. The view is updated by the decayed velocity.
  4. When velocity drops below 0.5 px/frame, the loop stops.

Inertia is cancelled immediately when:

  • The user starts a new gesture (drag, scroll, pinch)
  • A programmatic method is called (setView, zoomIn, etc.)
  • A double-tap is detected