For the complete documentation index, see llms.txt. Markdown variants are available by appending .md to any URL or sending an Accept: text/markdown header. The dithercn agent skill, for building any dither on the engine, is at /.well-known/agent-skills/dithercn/SKILL.md.
dithercn
GitHub

Rain

Rain on a window at night: a few big, soft city lights out of focus behind the glass, drops that show them flipped and brighter like tiny lenses, and bigger drops that slide down and leave wet trails.

Controls
Lights
Second lights
Drops1
Glow1
Scale1
Fade0
Animate

Installation

pnpm dlx shadcn@latest add https://dithercn.dev/r/rain.json

Usage

import { Rain } from "@/components/dithercn/rain";
 
export function Hero() {
  return (
    <section className="relative isolate min-h-[480px]">
      <Rain className="absolute inset-0 -z-10" />
      <h1>Your headline</h1>
    </section>
  );
}

The scene has two layers. Behind the glass, the city is a few big, soft discs of out-of-focus light, each in one of the palette's colours after the paper. Each is full in the middle and thins out to its edge. There are more of them low down along the street than up in the sky, over a faint glow that rises from the street, and they sway very slightly, as if the camera breathed.

On the glass, a scatter of beads sit still, and every so often a new one lands. Each bead is a tiny lens: it shows the light behind it upside down, shrunk and brighter, inside a dark rim. Just inside the rim it catches an arc of light on the side facing the brightest light near it, longer the brighter that light is, a short glint across from it, and a faint line round the rest of its edge. So a bead over a light glows in that light's colour, ringed in dark, and a bead over the dark sky is only its arc, glint and faint outline, each one turned its own way. A few bigger drops gather water for a moment, then slide down at an easy, uneven pace, slowing almost to a stop now and then and running on, stretching as they run. Each leaves a wavering wet trail, widest just behind the drop, where the film of water either side of it softly bends the lights, and tapering to a thin, dim thread higher up as it dries. The drop wipes the beads off its path; the beads come back one by one as the trail dries.

The lights scale with the box. The drops are measured in dither cells, so they keep their size on a phone and a wide screen shows more of them.

Examples

City lights

Red tail lights and orange street lamps, a brighter glow, a slightly higher scale for more, smaller lights and more drops give a busy street seen through a wet window.

Behind a headline

fade={1} clears the drops from an oval in the middle of the box and dims the lights behind it, as if someone had wiped the glass, so the text sits on dark, quiet ground. A lower glow keeps the lights around it calm.

Props

PropTypeDefault
drops

How many drops are on the glass, from 0 (dry glass, only the lights) to 2. Scales the beads and the drops that slide.

Type: numberDefault 1
glow

How bright the city lights behind the glass are, from 0 to 2. The drops brighten with them.

Type: numberDefault 1
scale

Size of the lights behind the glass. Higher values make more, smaller ones.

Type: numberDefault 1
fade

How far the drops clear and the lights dim in the middle of the box, from 0 to 1, to make room for text.

Type: numberDefault 0
palette

The paper, then one colour per kind of light: palette names such as "blue", CSS variable names, or any CSS colour. Each light takes one of them, and each drop the colour of the light behind it.

Type: [DitherColor, DitherColor, ...DitherColor[]]Default ["--dither-paper", "--dither-ink", "orange"]
matrix

The threshold pattern. See Dither engine.

Type: "bayer2" | "bayer4" | "bayer8" | "blue-noise"Default "blue-noise"
cell

Size of one dither cell in CSS pixels. The drops are measured in cells, so a bigger cell makes bigger drops.

Type: numberDefault --dither-cell
speed

How fast the drops slide and land. At 1 a big drop slides about 10 cells a second on average, slowing and speeding up as it goes.

Type: numberDefault 1
animate

false stops the motion: a still frame if it starts off, the current frame if it was moving.

Type: booleanDefault true
className

Size and position. The window fills this box.

Type: stringDefault –

Notes

  • It is decorative and hidden from assistive technology. Put real text on top of it, not inside it.
  • With reduced motion turned on, it draws one still frame, with drops caught mid-slide and their trails behind them, and stops.
  • It pauses when scrolled out of view or when the tab is hidden, and releases its WebGL context when far offscreen. Without WebGL it shows a still SVG of the same window: soft discs of light over the street's glow, beads ringed in dark with their arcs turned towards the lights, and a few big drops with their tapering trails, in the same colours.
  • On a light theme the paper is light and the lights are drawn in ink, like a printed negative. Pass a dark first palette colour, or set className="dark" on a wrapper, for night on any theme.
  • Every cell checks the nine nearest lights once, its own two bead squares and two sliding drops, with no loop over every drop. The colour pass repeats that work. See Performance.