Movement · a scroll mechanism, demonstrated

Every reveal
is wound,
not triggered.

Lenis reads your scroll like a mainspring reads a hand — smoothing raw input into steady motion. GSAP's ScrollTrigger is the escapement, releasing each animation exactly on beat. Scroll to see the mechanism run.

scroll
01
Lenis intercepts native scroll, replaces it with inertia
02
ScrollTrigger reads position, decides what fires and when
03
GSAP tweens the DOM — opacity, transform, timeline
Stage 01 — Input

Raw scroll is jumpy on purpose.

Browsers snap to the wheel event immediately. That's correct for reading text — and wrong for a page that wants to feel directed.

Stage 02 — Damping

Lenis adds lag, deliberately.

Every scroll input is smoothed through an easing curve before it touches the page — the same principle as a mainspring evening out hand torque.

Stage 03 — Trigger

ScrollTrigger watches position.

Each element declares a start and end point in the scroll timeline. Cross it, and a tween fires — pin, fade, translate, scrub.

Stage 04 — Release

This whole section is one pin.

You haven't scrolled the page — you've scrolled through a fixed frame, four beats wide, then handed back to normal flow.

Lenis

Momentum, not magic

~3kb, zero dependencies. It hijacks the scroll event, replays it with easing, and exposes a clean progress value everything else can hook into.

ScrollTrigger

The choreography layer

Free since Webflow's acquisition of GreenSock. Handles pins, scrubs, and reveals — the part that makes a page feel directed rather than just long.

Respect

prefers-reduced-motion

Check it, and skip the hijacking entirely for anyone who's opted out. The mechanism should be a choice, not a tax.

The mechanism is easy.
Everything around it is the actual work.

lenis + gsap · scrolltrigger · reduced-motion respected