KQ-1833 · GRADED/WASH
Graded Wash
A sheet of cold-press paper on a tilted board receives a graded watercolour wash: a flat brush lays it stroke by stroke, each stroke tops up a bead of wet paint along the bottom of the painted area, and the colour it carries hands over from the first to the second while the bead mixes what it holds, so the change is a true gradation. Between strokes gravity creeps the bead down the slope; dragging tips the board 1:1 in 3D — steeper, flatter or leaning — and the water runs along the bead to the low side, pooling and running further there, before the board settles back on springs.drift with the throw's velocity. Where the bead lingers it leaves soft tide lines, the wash dries lighter than it went on, and the board is focusable: the arrow keys tip it while held and Enter or Space lays a new wash.
Fernworks Atelier
Evening sky, a graded wash
ready · tilt 12° · drag to tip the board
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/graded-wash
Props
- colors
- "dusk" | "tide" | "ember" | "moss" | [string, string]
- default "dusk"
- The two colours, top into bottom: a named pair or two CSS colours.
- wetness
- number
- default 0.6
- How much water the wash carries: dry brush and quick to dry (0) to soft, pooling and slow to dry (1).
- tilt
- number
- default 12
- The board's resting slope in degrees, 0 (the bead stalls) to 30 (it runs).
- lean
- number
- default 0
- The board's resting lean to the side, −1 (left low) to 1 (right low).
- strokes
- number
- default 7
- How many strokes lay the wash, 4 to 12.
- pace
- number
- default 460
- How long one stroke takes to cross the paper, in ms.
- grain
- number
- default 0.5
- How much tooth the paper has, 0 (smooth) to 1 (rough and granulating).
- trigger
- "inView" | "mount" | "manual"
- default "inView"
- When the first wash is laid.
- washKey
- number
- default 0
- Change it to lay a new wash from outside.
- onStateChange
- (state: "ready" | "painting" | "drying" | "dry", stroke: number) => void
- default —
- Fires as the wash paints (once per stroke), dries and is dry.
- onComplete
- () => void
- default —
- Fires when a wash has dried.
- label
- string
- default "Watercolour wash"
- Names the board for assistive technology.
- disabled
- boolean
- default false
- Shows the wash but takes no input.
- dpr
- number
- default 2
- Cap on the canvas's device pixel ratio, at most 2.
- className
- string
- default —
- Sizes the board; give it a height. Defaults to h-52 w-full.
| Prop | Type | Default | Description |
|---|---|---|---|
| colors | "dusk" | "tide" | "ember" | "moss" | [string, string] | "dusk" | The two colours, top into bottom: a named pair or two CSS colours. |
| wetness | number | 0.6 | How much water the wash carries: dry brush and quick to dry (0) to soft, pooling and slow to dry (1). |
| tilt | number | 12 | The board's resting slope in degrees, 0 (the bead stalls) to 30 (it runs). |
| lean | number | 0 | The board's resting lean to the side, −1 (left low) to 1 (right low). |
| strokes | number | 7 | How many strokes lay the wash, 4 to 12. |
| pace | number | 460 | How long one stroke takes to cross the paper, in ms. |
| grain | number | 0.5 | How much tooth the paper has, 0 (smooth) to 1 (rough and granulating). |
| trigger | "inView" | "mount" | "manual" | "inView" | When the first wash is laid. |
| washKey | number | 0 | Change it to lay a new wash from outside. |
| onStateChange | (state: "ready" | "painting" | "drying" | "dry", stroke: number) => void | — | Fires as the wash paints (once per stroke), dries and is dry. |
| onComplete | () => void | — | Fires when a wash has dried. |
| label | string | "Watercolour wash" | Names the board for assistive technology. |
| disabled | boolean | false | Shows the wash but takes no input. |
| dpr | number | 2 | Cap on the canvas's device pixel ratio, at most 2. |
| className | string | — | Sizes the board; give it a height. Defaults to h-52 w-full. |