# 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.

> For the complete documentation index, see [llms.txt](/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](/.well-known/agent-skills/dithercn/SKILL.md).

> **This is an example, not the only option.** It is one component built on the dithercn engine. Install it when it is what you were asked for. For any other look, don't stretch its props to fit: write your own field on `DitherShader` ([Write your own dither](/docs/engine/write-your-own.md)), and read this example's source for technique. Its full source is in [https://dithercn.dev/r/rain.json](https://dithercn.dev/r/rain.json), under `files[].content`.

## Installation [#installation]

```bash
npx shadcn@latest add https://dithercn.dev/r/rain.json
```

## Usage [#usage]

```tsx
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 [#examples]

### City lights [#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.

```tsx title="examples/rain-city.tsx"
import { Rain } from "@/components/dithercn/rain";

export default function RainCity() {
  return (
    <Rain
      drops={1.1}
      glow={1.35}
      scale={1.15}
      palette={["--dither-paper", "red", "orange"]}
      className="absolute inset-0"
    />
  );
}
```

### Behind a headline [#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.

```tsx title="examples/rain-headline.tsx"
import { Rain } from "@/components/dithercn/rain";

export default function RainHeadline() {
  return (
    <section className="relative isolate flex size-full flex-col items-center justify-center gap-3 px-6 text-center">
      <Rain
        fade={1}
        glow={0.8}
        palette={["--dither-paper", "blue", "purple"]}
        className="absolute inset-0 -z-10"
      />
      <h3 className="max-w-sm text-3xl font-medium tracking-[-0.03em] text-balance">
        Stay in, the forecast can wait
      </h3>
      <p className="text-muted-foreground max-w-[18rem] text-sm text-pretty">
        A reading app for long evenings. Pick up the chapter you left on the
        train.
      </p>
    </section>
  );
}
```

## Props [#props]

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `drops` | `number` | `1` | How many drops are on the glass, from 0 (dry glass, only the lights) to 2. Scales the beads and the drops that slide. |
| `glow` | `number` | `1` | How bright the city lights behind the glass are, from 0 to 2. The drops brighten with them. |
| `scale` | `number` | `1` | Size of the lights behind the glass. Higher values make more, smaller ones. |
| `fade` | `number` | `0` | How far the drops clear and the lights dim in the middle of the box, from 0 to 1, to make room for text. |
| `palette` | `[DitherColor, DitherColor, ...DitherColor[]]` | `["--dither-paper", "--dither-ink", "orange"]` | 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. |
| `matrix` | `"bayer2" \| "bayer4" \| "bayer8" \| "blue-noise"` | `"blue-noise"` | The threshold pattern. See Dither engine. |
| `cell` | `number` | `--dither-cell` | Size of one dither cell in CSS pixels. The drops are measured in cells, so a bigger cell makes bigger drops. |
| `speed` | `number` | `1` | 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. |
| `animate` | `boolean` | `true` | false stops the motion: a still frame if it starts off, the current frame if it was moving. |
| `className` | `string` | `–` | Size and position. The window fills this box. |

## Notes [#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](/docs/engine/performance).