KQ-1561 · CELLULOID/COIL

Celluloid Coil

Pictures become frames on one long strip of film — sprocket holes cut through the base, frame numbers, stock and captions printed on the edge — wound in a loose helix through space in CSS 3D, each frame a plane on the chord between its ends so the strip never tears. The camera rides the strip and follows its turns, so travelling reads as the coil turning past you like a screw: each frame swings round to face you at the gate and curls away round the back; on first view the straight strip winds into its coil on springs.drift. Wheel, drag (1:1 at the gate) and flick travel along it and settle on the nearest frame on springs.glide with the release velocity; Left and Right step frames, Page keys step three, Home and End go to the ends.

KQ-1561 · CELLULOID/COIL

Waylight Pictures · location reel

Left and Right step from frame to frame, Page Up and Page Down by three, Home and End go to the ends of the reel.

frame 04 of 10 · glasshouse

Install

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

$ pnpm dlx shadcn@latest add @kinetiq/celluloid-coil

Props

items
CelluloidFrame[]
default defaultCelluloidFrames
The pictures, one per frame: { src?, alt, caption?, art? }.
value / defaultValue
number
default 0
The frame in the gate, controlled or initial.
onValueChange
(index: number) => void
default —
Fires from the drag, wheel, key or click that brought a new frame to the gate.
twist
number
default 0.4
How much the strip rolls about its own length, 0 to 1.
frameGap
number
default 14
Film between one picture and the next, px.
grain
number
default 0.35
Grain, dust and vignette on the pictures, 0 to 1; the grain shimmers only while the strip moves.
loop
number
default 0.6
How loose the coil is: radius and pitch of the turns, 0 to 1.
tilt
number
default 8
How far the camera looks down on the coil, degrees (-30 to 30).
aspect
number
default 1.5
Frame width over height.
stock
string
default "WAYLIGHT 400"
The film stock printed along the edge.
stripColor
string
default "oklch(from var(--warn) 0.2 0.012 h)"
The film base colour.
perspective
number
default 1000
Distance of the eye from the strip, px: smaller is a wider lens.
wheel
boolean
default true
The wheel travels the strip once the visitor has rested on it or tabbed in, and lets the page scroll at either end.
height
number
default 520
Height of the stage, px.
label
string
default "Film strip"
The strip's accessible name.
disabled
boolean
default false
Stops every gesture and key.
className
string
default —
Classes for the outer frame.