Installation
pnpm dlx shadcn@latest add https://dithercn.dev/r/dithered-logo.jsonUsage
import { DitheredLogo } from "@/components/dithercn/dithered-logo";
export function Brand() {
return <DitheredLogo src="/logo.svg" alt="Acme" className="h-8" />;
}Set a height with className; the width follows the logo's own ratio. The logo is drawn on a grid of whole device pixels and cut at half coverage, so every edge lands on a cell boundary instead of fraying into noise. A solid outline one cell wide keeps the shapes exact, and the inside takes the fill: a gradient that thins towards the bottom, dots, hatching, or solid ink.
By default every part of the logo becomes one ink, color. With tone="original" it keeps the file's own colours.
Examples
One treatment for many logos
Logos from different brands, drawn with the same fill and colour, read as one set. Here the hatched fill in grey.
Colour
The same three-colour mark with tone="original", and in one palette colour.
Scan line
A 3px cell turns the wordmark into pixel art. effect="scan" runs a bright line down it every period seconds and leaves solid ink behind for a moment.
Props
| Prop | Type | Default |
|---|---|---|
| src* SVG or PNG URL. Files from another origin need CORS headers. | Type: string | Default – |
| alt* The brand name for screen readers. "" hides the logo. | Type: string | Default – |
| color The ink. A palette name or any CSS colour. | Type: DitherColor | Default "ink" |
| tone One ink, or the file's own colours. | Type: "mono" | "original" | Default "mono" |
| fill Texture inside the shapes. | Type: "gradient" | "dotted" | "hatched" | "solid" | Default "gradient" |
| outline A solid outline one cell wide, so shapes stay exact with an open fill. | Type: boolean | Default true |
| floor Gradient fill: the share of ink left at the bottom of the logo. | Type: number | Default 0.3 |
| matrix Threshold pattern for the gradient fill and the effects. | Type: "bayer2" | "bayer4" | "bayer8" | "blue-noise" | Default "bayer4" |
| cell Size of one cell in CSS pixels. Larger cells give a chunkier, pixel-art mark. | Type: number | Default 1 |
| effect A diagonal band of solid ink, or a bright scan line, sweeping across the logo. | Type: "none" | "shimmer" | "scan" | Default "none" |
| period Seconds per sweep. | Type: number | Default 6 |
| phase Where in the sweep this logo starts, 0 to 1. Offsets logos in a row. | Type: number | Default 0 |
| source "alpha" for transparent backgrounds, "dark" for a dark logo on an opaque light background. | Type: "alpha" | "dark" | Default "alpha" |
| ratio Width over height. Set it to reserve space before the logo loads. | Type: number | Default The logo's ratio |
Notes
- The root has
role="img"with the brand name as its label. - SVGs need a
widthandheight(or aviewBoxthe browser can size) so the logo has a ratio. SVGs are rasterised by the browser at the exact cell size, so curves stay smooth. - Effects run at 30 fps only while the logo is on screen, and stop under reduced motion. Without one, the logo is drawn once and redrawn only on resize or theme change.