KQ-1857 · EAVES/DRIP

Eaves Drip

A small pixel-art cottage in quiet rain, and the water's whole way down: drops fall at the wind's angle and burst on the tiles leaving a wet glint, some of the water runs down the roof into the gutter and along it to the end, where a drop swells at the lip, lets go and falls into a puddle that slowly grows, each landing opening a ring. The pointer is the wind — lean either side of the middle and the rain leans with you, eased over a few hundred milliseconds — and a click sends a gust from that side that lifts a sheet of spray off the roof, the gutter and the puddle, which falls back as scattered drops. The scene is focusable: Left and Right step the wind and Enter sends a gust.

KQ-1857 · EAVES/DRIP
Move across the scene to change the wind; click or press Enter for a gust. Left and Right change the wind.

Fen Lane · next 2 h

Light rain · 11°

wind 0.3 → · puddle 0%

Install

One command — the source lands in your repo. Or copy it from the Code tab.

$ pnpm dlx shadcn@latest add @kinetiq/eaves-drip

Props

children
React.ReactNode
default —
Content above the scene, such as a caption; it stays fully interactive.
rainRate
number
default 0.5
How hard it rains, 0 (a few drops) to 1 (a downpour).
pixel
number
default 3
The size of one cell of the pixel art, 2 to 6 px.
puddle
number
default 0.6
How big the puddle may grow, 0 (a few cells) to 1 (wide).
wind
number
default 0.25
The resting wind, -1 (blowing left) to 1 (blowing right).
gust
number
default 0.7
Strength of a click's gust, 0 to 1.
palette
"auto" | "day" | "dusk" | "night"
default "auto"
The scene's colours: an overcast day on a light page and a night with a lit window on a dark one, or fixed.
windowLight
boolean
default true
Light the cottage window.
interactive
boolean
default true
The pointer sets the wind, a click sends a gust, and the keys do both.
sound
boolean
default false
Plips as a gust's spray and the next drips land; silent until a visitor clicks or presses a key.
onGust
(direction: -1 | 1) => void
default —
Fires when a gust is sent, with the way it blows.
onWindChange
(wind: number) => void
default —
Fires when the wind settles to a new value, rounded to one decimal.
onPuddleChange
(fill: number) => void
default —
How full the puddle is, 0 to 1, rounded to two decimals, at most twice a second.
paused
boolean
default false
Freeze the rain.
seed
number
default 2
Seeds the tiles, the hills and the rain.
label
string
default "Rain on a roof"
Accessible name.
className
string
default "h-52 w-full"
Sizes the scene.