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.

KQ-1469 · RIPPLE/LATTICE

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.