KQ-1471 · DOT/TIDE
Dot Tide
A background that is a regular dot grid, centred in the box, with a slow tide running through it: three long travelling waves sum into a height that raises and lowers every dot between a fine point and most of a cell, and the colour shifts along the wave from troughs washed into the page to crests in the full colour turned a little in hue. The tide rises gently under the hand, the mound following on springs.glide and arriving on springs.drift. A press sends a fast circular wave through the field, and every dot rides its own springs.recoil spring, so each dot the ring crosses pops up, overshoots back twice and settles, leaving a ringing, brightened wake; keyboard focus on a control inside raises the tide there and sends a softer wave from it.
Coldbrook Tides
High water at 06:42
Tide tables for the whole coast
cobalt · 16 px grid · tide 0.6×
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/dot-tide
Props
- children
- React.ReactNode
- default —
- The content on top of the field: a hero line, a heading, a call to action.
- spacing
- number
- default 16
- The distance between dots, px, 6 to 64.
- speed
- number
- default 0.6
- How fast the tide runs, 0 (slack water) to 2.
- color
- "cobalt" | "sea" | "ember" | "ink" | string
- default "cobalt"
- The dots' colour: a named one, or any CSS colour.
- size
- number
- default 0.72
- The largest dot, as a share of a cell, 0.2 to 1.
- swell
- number
- default 0.7
- How far the tide swings the dots between a fine point and full size, 0 to 1.
- angle
- number
- default 24
- Which way the tide runs, degrees anticlockwise from rightward.
- shift
- number
- default 0.5
- How far the colour turns in hue from trough to crest, 0 to 1.
- waveSpeed
- number
- default 720
- How fast a press's wave runs out through the field, px per second.
- interactive
- boolean
- default true
- The pointer and keyboard focus raise the tide, and a press sends a wave.
- pointerStrength
- number
- default 0.6
- How high the tide rises under the hand, 0 to 1.
- radius
- number
- default 140
- How far the rise under the hand reaches, px.
- paused
- boolean
- default false
- Stop the tide; waves and the hand still move the dots.
- seed
- number
- default 1
- Seeds where the tide starts, so two fields 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) raising the tide.
- onWave
- (x: number, y: number) => void
- default —
- Fires when a press or keyboard focus sends a wave, with where it started 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 field: a hero line, a heading, a call to action. |
| spacing | number | 16 | The distance between dots, px, 6 to 64. |
| speed | number | 0.6 | How fast the tide runs, 0 (slack water) to 2. |
| color | "cobalt" | "sea" | "ember" | "ink" | string | "cobalt" | The dots' colour: a named one, or any CSS colour. |
| size | number | 0.72 | The largest dot, as a share of a cell, 0.2 to 1. |
| swell | number | 0.7 | How far the tide swings the dots between a fine point and full size, 0 to 1. |
| angle | number | 24 | Which way the tide runs, degrees anticlockwise from rightward. |
| shift | number | 0.5 | How far the colour turns in hue from trough to crest, 0 to 1. |
| waveSpeed | number | 720 | How fast a press's wave runs out through the field, px per second. |
| interactive | boolean | true | The pointer and keyboard focus raise the tide, and a press sends a wave. |
| pointerStrength | number | 0.6 | How high the tide rises under the hand, 0 to 1. |
| radius | number | 140 | How far the rise under the hand reaches, px. |
| paused | boolean | false | Stop the tide; waves and the hand still move the dots. |
| seed | number | 1 | Seeds where the tide starts, so two fields 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) raising the tide. |
| onWave | (x: number, y: number) => void | — | Fires when a press or keyboard focus sends a wave, with where it started in px from the box's top left. |
| className | string | "h-full w-full" | Sizes and shapes the box. |