KQ-1585 · FLIPBOOK/PATH

Flipbook Path

A surface that turns the pointer's path into a flipbook: moving over open space lays the next page of a drawn sequence every few pixels — a paper card with a binding edge and its frame number — set down on springs.snap and leaning into the direction it was laid in, so the path becomes a fanned deck. Sweep back over the trail and the page under the pointer lifts on springs.flick with its neighbours rising a little, so the drawing plays in order under the pointer at the speed of the sweep, forward or backward; left alone, the trail clears from its oldest page. The surface is one tab stop: the arrow keys move a pen that lays and plays exactly as the pointer does, and Backspace clears the trail.

KQ-1585 · FLIPBOOK/PATH

Fernworks Animation School

Every line is a frame. Draw one, then play it back.

Move over open space to lay pages; move back over the trail to play them in order. The arrow keys move a pen that does the same, Shift for longer steps; Backspace clears the trail.

Fernworks · open studio

move to lay frames · sweep back to play them

Install

One command — the source lands in your repo. Or copy it from the Code tab.

$ pnpm dlx shadcn@latest add @kinetiq/flipbook-path

Props

frames
number
default 12
Pages in one cycle of the drawing (4 to 24); laid pages loop through it.
sequence
"bounce" | "flap" | "bloom" | "orbit"
default "bounce"
The built-in drawing: a ball with squash and stretch, a gull's wingbeat, a flower opening and closing, a moon passing in front of and behind its planet.
renderFrame
(ctx: CanvasRenderingContext2D, progress: number, size: number) => void
default —
Your own drawing for each page, into a square `size` CSS px wide at the origin; progress runs 0 to 1 across the cycle. Replaces sequence; pages are redrawn when the function's identity changes.
spacing
number
default 30
Travel between two laid pages, px (12 to 96).
frameSize
number
default 56
Width of a page, px (24 to 96); pages are 4:5 landscape.
fade
number
default 2.5
Seconds a trail left alone takes to clear, oldest page first.
hold
number
default 700
Milliseconds a trail waits, left alone, before it starts to clear.
lift
number
default 1.5
How far the page under the pointer rises, as a scale (1 to 2).
tilt
number
default 0.5
How far pages lean into the direction they were laid in, 0 to 1.
maxFrames
number
default 36
Most pages on the surface; past it the oldest fades.
resting
boolean
default true
Lay an S-curve of pages at rest (played once by an unseen hand on first view), and lay it again whenever the trail has cleared and the pointer has left.
paper
string
default "var(--card)"
Page colour, any CSS colour.
ink
string
default "var(--foreground)"
Drawing colour.
accent
string
default "var(--accent-bright)"
The drawings' one fill colour, and the lifted page's edge.
paused
boolean
default false
Freeze the pages where they are; nothing lays, lifts or fades.
seed
number
default 3
Seeds the pages' hand-laid jitter and the resting curve.
dpr
number
default 2
Cap on the canvas's device pixel ratio, at most 2.
disabled
boolean
default false
The surface ignores the pointer and the keys, leaves the tab order and lets touch scroll.
label
string
default "Flipbook path"
The surface's accessible name.
onFrame
(frame: number, of: number) => void
default —
Fires when the page under the pointer (or the keyboard's pen) changes, with its frame (1-based) and the cycle length.
onTrail
(count: number, resting: boolean) => void
default —
Fires when the number of pages on the surface changes; resting is true when the component laid them itself.
className
string
default "h-56 w-full"
Sizes and shapes the surface; pages stay inside it.