KQ-1416 · FILM/GRAIN

Film Grain

Film grain over any section, built for cost: two seamless grain tiles per seed — fine noise plus clumped octaves blurred on the torus — are made once and shared, and each projected frame at the chosen frame rate only swaps which tile shows and jumps it to a seeded offset, so the compositor does the work and no WebGL context is used. Dark specks multiply and light specks screen, so the grain reads on light and dark pages alike, with optional gate weave, faint scratches, a vignette and a wavering lamp; the projector spins up from 4 fps the first time it is in view. Under the mouse, and around a control with keyboard focus, the grain clears in a soft patch that follows on springs.glide and fades in and out on tweens.

KQ-1416 · FILM/GRAIN

Coldbrook · small batch No. 14

Night Roast

projecting · 18 fps · move across to clear the grain

Install

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

$ pnpm dlx shadcn@latest add @kinetiq/film-grain

Props

children
ReactNode
default —
The section under the grain. It stays fully interactive and selectable.
intensity
number
default 0.5
How strong the grain is, 0 to 1.
size
number
default 1
Grain size: 1 is fine 35mm stock, 3 coarse 16mm (0.5 to 3).
fps
number
default 18
The projector's frame rate: how many times a second the grain changes (1 to 30).
blend
"dual" | "overlay" | "soft-light"
default "dual"
How the grain meets the page: dual darkens with dark specks and lightens with light ones, so it reads on light and dark; overlay and soft-light work the midtones only.
weave
number
default 0
Gate weave: how far the section drifts in the gate from frame to frame, in px (0 to 2).
scratches
number
default 0.2
How often faint scratches run down the frame, 0 to 1.
vignette
number
default 0.3
The darkening toward the corners, 0 to 1.
flicker
number
default 0.2
How much the lamp's brightness wavers from frame to frame, 0 to 1.
calm
number
default 0.5
How much the grain clears around the mouse and around a focused control, 0 to 1.
calmRadius
number
default 140
The radius of that clear patch, in px.
intro
boolean
default true
Spin the projector up the first time the section comes into view.
interactive
boolean
default true
The mouse and keyboard focus clear the grain around them.
paused
boolean
default false
Holds one frame of grain and stops the projector.
seed
number
default 24
Seed for the grain tiles and every flaw. Sections with the same seed share their tiles.
dpr
number
default 2
The highest device pixel ratio the grain is drawn for: one grain pixel per device pixel up to this (never above 2).
className
string
default —
Classes for the section box.