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

Flow field

A wind map drawn as a dither: streamlines of a slowly turning, swirling flow, with bright streaks that travel along them and leave fading tails.

Controls
Colour
Style
Density1
Trail0.55
Turbulence1
Wind angle70°
Animate

Installation

pnpm dlx shadcn@latest add https://dithercn.dev/r/flow-field.json

Usage

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

The wind is a steady breeze along angle, bent by slow swirls that drift downwind and change shape as they go. The streamlines are the level lines of its stream function, so they never cross, and they bunch together where the wind runs fast. Bright streaks travel along each line at their own pace, with a crisp head and a tail that fades behind it. Streaks in fast wind are brighter than those in still air, and the prevailing direction veers a few degrees back and forth over time. The swirls keep their size in pixels, so a narrow box shows a smaller piece of the same wind rather than a squashed one.

Examples

Weather map

variant="lines" draws every streamline in the first colour after the paper, and the streaks run through the rest of the palette as they brighten, so the colour reads as wind speed. More density and turbulence, and a higher scale for smaller swirls, fill the box with eddies, and levels={19} puts each of the four colours on an exact step.

Behind a headline

Fewer lines, a low turbulence and long trails give a calm, even breeze. Two soft tints of the ink keep the brightest streak well below full contrast, so the text reads on top.

Props

PropTypeDefault
variant

streaks draws only the travelling dashes. lines also draws every streamline underneath them.

Type: "streaks" | "lines"Default "streaks"
density

How tightly the streamlines pack. 2 packs twice as many in.

Type: numberDefault 1
trail

Length of each streak's fading tail, as a share of the gap between streaks, from 0.1 to 1.

Type: numberDefault 0.55
turbulence

How much the wind meanders and curls into eddies, from 0 (a straight, steady wind) to 2.

Type: numberDefault 1
scale

Size of the swirls. Higher values pack more, smaller ones in.

Type: numberDefault 1
angle

Direction the wind blows towards, in degrees as in CSS: 0 points up, 90 right.

Type: numberDefault 70
intensity

The brightest tone, from 0 to 1. Lower it to sit text on top.

Type: numberDefault 1
palette

Colours from paper to ink: palette names such as "blue", CSS variable names, or any CSS colour. Streamlines take the second colour; streaks brighten through the rest.

Type: [DitherColor, DitherColor, ...DitherColor[]]Default Paper, a tint of --dither-ink, then --dither-ink
matrix

The threshold pattern. See Dither engine.

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

Size of one dither cell in CSS pixels.

Type: numberDefault --dither-cell
speed

How fast the wind blows and the swirls drift.

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 wind 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 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 straight CSS lines along the wind in the same colours, cut into dashes, spaced by density and with tails as long as trail sets.
  • It samples the stream function three times per cell, at 30 fps and one pixel per dither cell. See Performance.