Installation
pnpm dlx shadcn@latest add https://dithercn.dev/r/ripples.jsonUsage
import { Ripples } from "@/components/dithercn/ripples";
export function Hero() {
return (
<section className="relative isolate min-h-[480px]">
<Ripples className="absolute inset-0 -z-10" />
<h1>Your headline</h1>
</section>
);
}Each point in sources sends out rings that fade with distance. A lone ring stops at the middle colour; where rings from two points cross, they add up to full ink, so the interference pattern shows up as bright knots. A slow swell bends the rings slightly so they don't look drawn with a compass.
Examples
One drop
A single source just below the frame sends rings up the box. They fade out before they reach the text at the top, and a little less intensity keeps the nearest ones soft.
Rain
Four sources, tighter rings and a faster decay through the chart colours. The 8×8 matrix gives the fading rings a finer grain.
Props
| Prop | Type | Default |
|---|---|---|
| sources Where the rings start, as fractions of the box from the top left. One to four points; values outside 0 to 1 put a point out of frame. | Type: [x: number, y: number][] | Default [[0.28, 0.38], [0.74, 0.66]] |
| rings How many rings fit in the height of the box. | Type: number | Default 12 |
| decay How quickly the rings fade away from their source. 0 keeps them strong across the box. | Type: number | Default 1 |
| intensity The brightest tone, from 0 to 1. Lower it to put text on top. | Type: number | Default 1 |
| palette Colours from paper to ink: palette names such as "blue", CSS variable names, or any CSS colour. | 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 "bayer4" |
| cell Size of one dither cell in CSS pixels. | Type: number | Default --dither-cell |
| speed How fast the rings travel outwards. | Type: number | Default 1 |
| animate false draws one still frame. | Type: boolean | Default true |
| className Size and position. The rings fill this box. | Type: string | Default – |
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 rings drawn with CSS gradients.