KQ-1533 · DUST/DEVIL

Dust Devil

A tall funnel of fine light threads spiralling up from a floor in Canvas 2D, tight at the foot and loose at the crown, with dust circling its skirt: each thread winds round a spine of twenty nodes, spinning faster low down, drawn dim behind and bright in front, dense at the skirt and wispy at the crown. The foot walks after the pointer on springs.glide while every node above chases the one below on its own underdamped spring, softer toward the top, so the column bends as it walks and the crown whips past and settles when it stops; a click flings a spray of dust off the skirt along the spin. It is a slider for where it stands: arrow keys walk the foot and Enter flings dust.

KQ-1533 · DUST/DEVIL

Arrow keys walk the whirlwind across; Enter flings dust off its skirt.

Fieldline · trail report

Dry wind on the east mesa

standing at 50% · 24 threads

Install

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

$ pnpm dlx shadcn@latest add @kinetiq/dust-devil

Props

turns
number
default 3.5
How many times each thread winds round the column from foot to crown, 1 to 8.
lean
number
default 0.6
How far the crown trails the foot and whips past when it stops, 0 (a stiff column) to 1 (a whippy one).
threadCount
number
default 24
How many threads of light make the funnel, 6 to 64.
color
string
default "oklch(from var(--warn) 0.8 0.09 h)"
The light's colour: sand from the warn token's hue. Drawn additively on a dark page and as ink on a light one.
flare
number
default 0.55
The crown's width, as a share of the box's width, 0.2 to 0.9.
height
number
default 0.82
The funnel's height, as a share of the box's height, 0.4 to 0.95.
speed
number
default 1
How fast it spins, 0 (held) to 2.
dust
number
default 0.6
How much dust circles the skirt and how big a spray a click flings, 0 to 1.
wander
number
default 0.5
How far the foot wanders round its spot when no hand leads it, 0 to 1.
step
number
default 8
Percent of the width per arrow key.
value / defaultValue
number
default 50
Where it stands, 0 (left) to 100 (right), across the room the crown allows. Controlled or initial.
onValueChange
(value: number) => void
default —
Fires when the pointer (on leaving) or the keys set a new place, in whole percent.
interactive
boolean
default true
The pointer and keys walk it, and a click flings dust.
disabled
boolean
default false
No walking or flinging by hand or key.
paused
boolean
default false
Hold the spin and the wander; the walk and a fling still move.
seed
number
default 1
Seeds the threads and the dust, so two whirlwinds never match.
dpr
number
default 2
Cap on the canvas's device pixel ratio, at most 2.
label
string
default "Move the whirlwind"
The accessible name of the whirlwind's control.
onFling
() => void
default —
Fires when a click or Enter flings dust off the skirt.
className
string
default —
Sizes the box; it fills its parent by default (h-full w-full).