KQ-1469 · RIPPLE/LATTICE
Ripple Lattice
A background that is a fine square lattice of hairlines, centred in the box, whose lines are pushed by ripples: each a wave packet spreading from where it fell, a leading crest with a short train of wavelets behind, decaying with age and spreading with distance. Up to thirty-two sum as vectors, so crossing rings interfere into a moire of pinched and stretched cells, and the lines thicken and brighten at the crests. A moving pointer leaves a wake of small ripples as strong as it is quick, a press drops a stone, denting the mat under it so it bounces back twice on springs.recoil while the ring spreads with a softer echo behind it, and keyboard focus on a control inside drops one from that control.
Basinworks
Surfaces that answer back
Pressure mats for studios and labs
cobalt · 24 px cells · strength 0.60
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/ripple-lattice
Props
- children
- React.ReactNode
- default —
- The content on top of the grid: a hero line, a heading, a call to action.
- spacing
- number
- default 24
- The distance between grid lines, px, 8 to 96.
- strength
- number
- default 0.6
- How hard a ripple pushes the lines, 0 (not at all) to 1 (hard enough that the crests just begin to fold).
- color
- "ink" | "cobalt" | "signal" | "rose" | string
- default "cobalt"
- The lines' colour: a named one, or any CSS colour.
- lineWidth
- number
- default 1
- The lines' width, px.
- wavelength
- number
- default 56
- The distance between the wavelets in a ripple, px; longer waves also push farther.
- speed
- number
- default 260
- How fast a ripple spreads, px per second.
- decay
- number
- default 1.1
- How long a ripple lasts, seconds: its amplitude's time constant.
- crest
- number
- default 0.7
- How much the lines thicken and brighten at the crests, 0 to 1.
- drizzle
- number
- default 0.3
- Soft drops falling on the grid by themselves, 0 (none: the grid rests flat) to 1.
- trail
- boolean
- default true
- A moving pointer leaves a wake of small ripples.
- interactive
- boolean
- default true
- The pointer and keyboard focus ripple the grid.
- paused
- boolean
- default false
- Stop the drizzle; the hand still ripples the grid.
- seed
- number
- default 1
- Seeds where the drizzle falls, so two grids never match.
- dpr
- number
- default 2
- Cap on the canvas's device pixel ratio, at most 2.
- onActiveChange
- (active: boolean) => void
- default —
- Fires when the pointer or keyboard focus starts (true) or stops (false) rippling the grid.
- onRipple
- (x: number, y: number) => void
- default —
- Fires when a press or keyboard focus drops a ripple, with where it fell in px from the box's top left.
- className
- string
- default "h-full w-full"
- Sizes and shapes the box.
| Prop | Type | Default | Description |
|---|---|---|---|
| children | React.ReactNode | — | The content on top of the grid: a hero line, a heading, a call to action. |
| spacing | number | 24 | The distance between grid lines, px, 8 to 96. |
| strength | number | 0.6 | How hard a ripple pushes the lines, 0 (not at all) to 1 (hard enough that the crests just begin to fold). |
| color | "ink" | "cobalt" | "signal" | "rose" | string | "cobalt" | The lines' colour: a named one, or any CSS colour. |
| lineWidth | number | 1 | The lines' width, px. |
| wavelength | number | 56 | The distance between the wavelets in a ripple, px; longer waves also push farther. |
| speed | number | 260 | How fast a ripple spreads, px per second. |
| decay | number | 1.1 | How long a ripple lasts, seconds: its amplitude's time constant. |
| crest | number | 0.7 | How much the lines thicken and brighten at the crests, 0 to 1. |
| drizzle | number | 0.3 | Soft drops falling on the grid by themselves, 0 (none: the grid rests flat) to 1. |
| trail | boolean | true | A moving pointer leaves a wake of small ripples. |
| interactive | boolean | true | The pointer and keyboard focus ripple the grid. |
| paused | boolean | false | Stop the drizzle; the hand still ripples the grid. |
| seed | number | 1 | Seeds where the drizzle falls, so two grids never match. |
| dpr | number | 2 | Cap on the canvas's device pixel ratio, at most 2. |
| onActiveChange | (active: boolean) => void | — | Fires when the pointer or keyboard focus starts (true) or stops (false) rippling the grid. |
| onRipple | (x: number, y: number) => void | — | Fires when a press or keyboard focus drops a ripple, with where it fell in px from the box's top left. |
| className | string | "h-full w-full" | Sizes and shapes the box. |