KQ-1249 · FERRO/POOL
Ferro Pool
A canvas backdrop of a ferrofluid pool seen at a low angle — glossy near-black at the front, reflecting more of the room toward the back, with a softbox lying on it as a long soft band. The pointer is a magnet: its footprint is found through the same perspective that draws the pool, every site of a jittered hexagonal lattice feels its field, and above a threshold each rises into a spike on its own underdamped spring, so the crown jiggles up, leans along the field lines toward the magnet, stands on a mound that bulges beneath it and sinks back with a wobble when the magnet leaves, every spike shaded by a lit flank, a specular line and a rim on the side the slowly drifting light comes from. A click pulses the field — it surges and a ring runs out across the pool kicking every spike it passes — and the keyboard path is a role="application" surface where focus brings the magnet in, arrow keys move it and Enter or Space pulse.
Basinworks field notes
Magnetic fluids, issue 12
Arrow keys move a magnet over the pool, Shift for larger steps; the fluid rises into spikes beneath it. Enter or Space pulses the field.
pool at rest · hover, then click to pulse
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/ferro-pool
Props
- strength
- number
- default 0.6
- The magnet, 0 to 1: how far its field reaches across the pool, how tall the spikes grow and how far they lean toward it. On a resting pool a change holds the magnet over the middle for a moment, so the new crown shows.
- spikes
- number
- default 16
- Spikes across the pool's front edge, 8 to 32: a few tall cones or a dense bristle. The lattice is seeded, so it is the same pool every time. On a resting pool a change shows itself the same way.
- sheen
- number
- default 0.6
- How much the fluid shines, 0 to 1: the lit flanks, specular lines, rims and the softbox's reflection. 0 is matte ink, and a matte pool stops drawing once it is flat.
- label
- string
- default "Ferrofluid pool"
- The accessible name of the keyboard surface.
- onPulse
- () => void
- default —
- A click, a tap, Enter or Space pulsed the field.
- disabled
- boolean
- default false
- Ambient only: the pool ignores the pointer and the keyboard and leaves the tab order.
- children
- React.ReactNode
- default —
- What sits over the pool — a hero, a heading — in a layer above it. Presses on its own controls never pulse the field.
- className
- string
- default —
- Classes for the root, which fills its container (h-full w-full); set its size and radius here.
| Prop | Type | Default | Description |
|---|---|---|---|
| strength | number | 0.6 | The magnet, 0 to 1: how far its field reaches across the pool, how tall the spikes grow and how far they lean toward it. On a resting pool a change holds the magnet over the middle for a moment, so the new crown shows. |
| spikes | number | 16 | Spikes across the pool's front edge, 8 to 32: a few tall cones or a dense bristle. The lattice is seeded, so it is the same pool every time. On a resting pool a change shows itself the same way. |
| sheen | number | 0.6 | How much the fluid shines, 0 to 1: the lit flanks, specular lines, rims and the softbox's reflection. 0 is matte ink, and a matte pool stops drawing once it is flat. |
| label | string | "Ferrofluid pool" | The accessible name of the keyboard surface. |
| onPulse | () => void | — | A click, a tap, Enter or Space pulsed the field. |
| disabled | boolean | false | Ambient only: the pool ignores the pointer and the keyboard and leaves the tab order. |
| children | React.ReactNode | — | What sits over the pool — a hero, a heading — in a layer above it. Presses on its own controls never pulse the field. |
| className | string | — | Classes for the root, which fills its container (h-full w-full); set its size and radius here. |