Dither
ditherApplies ordered dithering and palette quantization to animated noise waves.
Usage
Basic usage
Put it into the relative + overflow-hidden container. The component comes with absolute inset-0 z-0, and the content is stacked on top with z-10.
<div className="relative h-56 overflow-hidden rounded-xl bg-neutral-950">
<Dither />
<div className="relative z-10 flex h-full items-center justify-center text-white/80">
Dither
</div>
</div>Pixel Art (Coarse Mosaic)
Increase pixelSize to make the dither particles thicker, and get the 8-bit retro texture with fewer color levels.
<Dither pixelSize={6} colorNum={3} />Delicate color gradation
colorNum The larger, the more color levels, and the smoother and more delicate the texture.
<Dither colorNum={8} pixelSize={2} waveSpeed={0.08} />Customized ripple color
Pass waveColor to overwrite the default chart token; any CSS color (hex / oklch / rgb) is acceptable.
<Dither waveColor="oklch(0.72 0.22 40)" colorNum={4} pixelSize={3} />Freeze still frame
disableAnimation The frozen waveform is a static picture (equivalent to reduced-motion), suitable for static covers.
<Dither disableAnimation waveColor="oklch(0.72 0.22 40)" />When to Use
Use it for an 8-bit, pixel-art ripple backdrop on nostalgic landing pages, game interfaces, or playful brand pages. Use Balatro for painted swirls, Beams for light curtains, or DotPattern for a regular dot matrix. Dither is the option built specifically around ordered dithering and color quantization.
Import
import { Dither } from "@hulianui/ui"Props
| Name | Type | Default | Description |
|---|---|---|---|
| waveSpeed | number | 0.05 | Ripple flow speed; frozen to static image under reduced-motion |
| waveFrequency | number | 3 | FBM frequency multiplier; higher values create finer ripple detail |
| waveAmplitude | number | 0.3 | Per-octave amplitude factor; higher values preserve more high-frequency detail |
| waveColor | string | --color-chart-1 | Main ripple color; accepts any CSS color and defaults to a light/dark theme token |
| colorNum | number | 4 | Quantized color-step count used with the Bayer matrix; lower values look more 8-bit |
| pixelSize | number | 2 | Dither-block size; higher values produce a coarser mosaic |
| disableAnimation | boolean | false | Freeze the wave field on a still frame, matching reduced-motion behavior |
| className | string | — | Class name forwarded to the canvas or fallback div |
Slots
| Slot | Type | Description |
|---|---|---|
| fallback | ReactNode | Static non-WebGL content for SSR, reduced motion, or unavailable WebGL; defaults to a checkerboard gradient |
Usage Guidelines
- WebGL client rendering: this effect relies on OGL and a single-pass shader. SSR renders the checkerboard-gradient
fallback; do not import the realtime implementation directly into a server component. - Token colors require the `--color-` prefix: pass
waveColor="var(--color-chart-1)". Bare names such asvar(--chart-1)do not resolve. See [[hulian-token-color-var-needs-color-prefix]]. - Lower
colorNumvalues strengthen the 8-bit look, but very low values such as 2 discard substantial detail. - The parent container must be
relative+overflow-hidden.
Related
DotPattern · GridPattern · StripedPattern · Spotlight · RetroGrid · Ripple
Playground
<div className="relative h-56 overflow-hidden rounded-xl"
style={{ background: "oklch(0.14 0.02 255)" }}>
<Dither
colorNum={4}
pixelSize={2}
waveSpeed={0.05}
disableAnimation={false}
/>
</div>