Glyph Field
PointerA field of braille dots that reads as a flowing contour map: two waves cross it, the colour turns along a sunset arc, and the cursor carves a trail that decays one dot at a time.
Draws slow noise waves on the GPU, ordered-dithered into pixel cells of one colour on the page's ground, for the look of a 1-bit screen. The pointer lifts the field around it. The drawing buffer is one pixel per cell, scaled up pixelated by CSS, so the shader touches a ninth of the pixels at the default cell. Every constant is a custom property re-read when the element's style changes. Without WebGL2 or JavaScript a still dot grid stands in. Fills its positioned parent.
Dither.
move your cursor
Live, from the library itself: scroll, hover, navigate away and back. The demo is never gated.
Adjust · props are custom properties, set inline, so you edit the running instance
JavaScript with its libs
10.8 kB raw
1.2 kB raw of its own, 776 B gzip. The rest is the runtime, the shader runner, the canvas helper and the GL core, loaded once for every effect on the page.
CSS 5.1 kB raw including the base tokens. Measured from a production build, and again in CI for every change that can move it.
Browser support
Chrome 56 · Firefox 51 · Safari 15; needs webgl2. Elsewhere: without WebGL2, a still dot grid in the colour, fading toward the edges.
The demo above is never gated; the source is. With a key in components.json (see account), the registry serves it like any other item:
npx shadcn@latest add @moonarc-pro/dither<section class="relative min-h-[60vh]">
<Dither color="var(--primary)" pixel={3} />
<h1 class="relative">A 1-bit dither background</h1>
</section>Without a key the registry answers 401 with an upgrade message. Related free primitives: glyph-field.
| Prop | Type | Default | Description |
|---|---|---|---|
color | string | 'oklch(0.62 0.19 262)' | Dot colour; any CSS colour, theme tokens included. Re-read when the theme changes. |
pixel | number | 3 | Cell size in CSS px. The canvas is one pixel per cell, so a larger cell is also cheaper. |
scale | number | 2.4 | Waves across the short side. |
speed | number | 1 | Wave speed multiplier; a change never jumps the waves (time is accumulated). |
density | number | 0.02 | Tone added everywhere: 0 leaves the troughs empty, 0.3 fills them with a light dither. |
contrast | number | 0.95 | How bright the wave ridges get. |
levels | number | 2 | Tone steps per cell: 2 is 1-bit, 4 adds two partial tones. |
lift | number | 0.5 | How much the pointer lifts the field around it; 0 turns the pointer off. |
No loop: one frame at a fixed moment is drawn and kept; the pointer does not lift it.
ClientRouterBound through the shared runtime: loop, observers and pointer listener are released before the swap and the WebGL context is lost on purpose after it; five round trips leave one context. Under transition:persist the canvas keeps its context and starts again on the next page.
Replaces: Dither (React Bits) · Dithering shaders (Paper). See the migration table.
A field of braille dots that reads as a flowing contour map: two waves cross it, the colour turns along a sunset arc, and the cursor carves a trail that decays one dot at a time.
Draws a sheet of fabric drifting in slow folds, lit from one side: a warped height field on the GPU, normals from finite differences, a diffuse body in the colour and a narrow sheen in a second tone.
Also: view transitions · how costs are measured · browser support · accessibility policy · five-minute setup · MCP for agents · this page as Markdown