KQ-1577 · LIGHT/WAND
Light Wand
A dark room with your content in it and the cursor a light wand: moving it paints a glowing tube whose colour walks through the palette along its length, a hot core in a coloured halo built from additive stamps so crossings over-expose toward white like film, and fast strokes run thinner and hotter. The first movement opens the shutter and a corner readout counts the exposure down while every stroke holds; then the frame blinks once and the light fades from oldest to newest along the stroke's own timeline. Arrow keys move the wand on springs.glide and paint, Enter or Space closes the shutter, and when first seen an unseen hand paints one coiled stroke so the room never opens empty.
Basinworks Night School · Thursdays
Paint with light.
Move the pointer to paint with light. Arrow keys move the wand and paint; Enter or Space closes the shutter.
dark room · move to open the shutter
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/light-wand
Props
- children
- React.ReactNode
- default —
- The content standing in the room: a headline, a call to action. It stays fully interactive.
- exposure
- number
- default 4
- How long the shutter stays open once the wand starts moving, seconds (0.5 to 30).
- palette
- "spectrum" | "ember" | "ice" | "sodium"
- default "spectrum"
- The colours the wand walks through along its stroke.
- colors
- string[]
- default —
- Two to eight CSS colours that replace palette.
- thickness
- number
- default 6
- The tube's thickness at rest, px.
- colorLength
- number
- default 420
- How much stroke one walk through the palette takes, px.
- speedThinning
- number
- default 0.6
- How much speed thins the tube and burns its core whiter, 0 to 1.
- glow
- number
- default 0.6
- How wide the glow round the tube spreads, 0 to 1.
- fadeTime
- number
- default 1200
- How long the light takes to fade from oldest to newest once the shutter closes, ms.
- dwell
- boolean
- default true
- A wand held still burns a brighter spot, as it would on film.
- shutter
- boolean
- default true
- Show the shutter's readout in the corner.
- autoPaint
- boolean
- default true
- When first seen, an unseen hand paints one stroke, so the room never opens empty.
- interactive
- boolean
- default true
- The pointer and the keys paint.
- disabled
- boolean
- default false
- Nothing paints and the keyboard's way in is off.
- paused
- boolean
- default false
- Hold the exposure where it is.
- dpr
- number
- default 2
- Cap on the canvas's device pixel ratio, at most 2.
- label
- string
- default "Light painting"
- The room's accessible name, for the keyboard's way in.
- onExposureStart
- () => void
- default —
- The shutter opened.
- onExposureEnd
- (length: number) => void
- default —
- The shutter closed, with how much light was painted, px of stroke.
- className
- string
- default "h-56 w-full"
- Sizes the room.
| Prop | Type | Default | Description |
|---|---|---|---|
| children | React.ReactNode | — | The content standing in the room: a headline, a call to action. It stays fully interactive. |
| exposure | number | 4 | How long the shutter stays open once the wand starts moving, seconds (0.5 to 30). |
| palette | "spectrum" | "ember" | "ice" | "sodium" | "spectrum" | The colours the wand walks through along its stroke. |
| colors | string[] | — | Two to eight CSS colours that replace palette. |
| thickness | number | 6 | The tube's thickness at rest, px. |
| colorLength | number | 420 | How much stroke one walk through the palette takes, px. |
| speedThinning | number | 0.6 | How much speed thins the tube and burns its core whiter, 0 to 1. |
| glow | number | 0.6 | How wide the glow round the tube spreads, 0 to 1. |
| fadeTime | number | 1200 | How long the light takes to fade from oldest to newest once the shutter closes, ms. |
| dwell | boolean | true | A wand held still burns a brighter spot, as it would on film. |
| shutter | boolean | true | Show the shutter's readout in the corner. |
| autoPaint | boolean | true | When first seen, an unseen hand paints one stroke, so the room never opens empty. |
| interactive | boolean | true | The pointer and the keys paint. |
| disabled | boolean | false | Nothing paints and the keyboard's way in is off. |
| paused | boolean | false | Hold the exposure where it is. |
| dpr | number | 2 | Cap on the canvas's device pixel ratio, at most 2. |
| label | string | "Light painting" | The room's accessible name, for the keyboard's way in. |
| onExposureStart | () => void | — | The shutter opened. |
| onExposureEnd | (length: number) => void | — | The shutter closed, with how much light was painted, px of stroke. |
| className | string | "h-56 w-full" | Sizes the room. |