Feature Playground

Scroll-driven · 1.7

Scroll-scrubbed frame sequence

A flipbook you thumb at your own speed.

Scroll position scrubs a pre-rendered image sequence frame by frame on a canvas, so a scene plays exactly as fast as you pull it.

4 knobs

How it actually works

This is the heaviest technique in the index, and the code is the easy half. The real problem is the asset pipeline: how many frames, at what quality, preloaded how, inside what memory ceiling. So this page puts a live counter on exactly that. Turn frame count and frame quality and watch the megabytes. Turn preload strategy and watch the per-frame cost in milliseconds. That trade is the feature.

Not by scrubbing a video element. That stutters, and iOS Safari has documented bugs. You extract the frames to a numbered set, decode them into ImageBitmaps held in memory, and drawImage the right one per scroll update inside rAF. Keeping the bitmaps pre-decoded is the whole trick: it makes the browser do less work per frame. scrollFraction = scrollTop / maxScrollTop, then frameIndex = floor(scrollFraction * frameCount). The canvas is fixed and the body carries several hundred vh of scroll distance.

The knobs, named

Frame count, scroll distance, preload strategy, frame quality. The HUD is the point: every knob here reports what it costs you in memory or in milliseconds, because that is the only honest way to teach this one.

KnobSourceWhat it teaches
Frame count sourced How many frames the sequence holds. Smoothness against weight, and the megabyte readout moves with it.
Scroll distance sourced Track height. Long distance over few frames is a slideshow; short distance over many frames skips most of them.
Preload strategy sourced Pre-decoded is the sourced trick: pay once at init, drawImage per frame. On demand pays per frame instead, and the HUD shows what that costs.
Frame quality sourced Bitmap resolution as a fraction of the canvas. This is the other half of the memory bill, and it is the one nobody budgets for.

sourced means the source names this parameter. ours means the source names none and the knob is our design against the mechanism. No knob here is invented and passed off as sourced.

Evidence

VERIFIED (author)

Mechanism from a CSS-Tricks reconstruction, cited independently by awwwards.md and craft-web.md. Apple's own source is INFERRED: apple.com was never rendered, and the index states that gap rather than papering over it.

Seen on
apple.com product pages (AirPods Pro is the cited example) — attribution INFERRED, not confirmed.
Dependencies
vanilla canvas; GSAP ScrollTrigger commonly drives the index
Difficulty
hard — and not the code: the asset pipeline is the real problem
Performance
The heaviest technique in this index. Hundreds of real frames run to tens of megabytes, hostile on mobile data and to memory ceilings. The HUD on this page reports our own memory estimate live.
Accessibility and the floor
Breaks entirely without JS, so it needs a static fallback image (the end frame) and aria-hidden on the canvas, with the real content as text. Under reduced motion ours renders that end frame: the last frame is the one that carries the message.
Where our build departs from the source: Our frames are generated procedurally at init, not extracted from a video and downloaded. The decode-and-draw mechanism, the frame maths and the memory profile are real; the network cost, which is the thing that actually makes this technique expensive in production, is absent from our version.

Notes

Composability. Nothing composes with it. It wants a fixed canvas and all your memory. Give it its own section or do not use it.

Our sequence is rendered procedurally at init instead of being loaded from a numbered set of JPEGs, because this build ships zero external assets. That is a real departure and it changes the honest thing about this feature: our frames cost no network and no download, which is precisely the cost that makes this technique hostile on mobile data. The mechanism below the frames is identical. The bill is not.