Skip to content
Sign in
EffectsDither imageMenu

Dither imagePro

Any image rendered dithered: Bayer 2, 4 and 8 and blue noise in a shader, Floyd-Steinberg, Atkinson and Sierra Lite in a worker, with ink and paper from your tokens and cells snapped to device pixels.

ProA portrait in four dither methods and three cell sizes. Hover or focus to see the original.

Installation

$ pnpm dlx shadcn@latest add @chatcn-pro/dither-image

Usage

tsx
import { DitherImage } from "@/components/ui/chatcn/pro/dither-image"

<DitherImage src={image.url} alt={image.prompt} algorithm="atkinson" aspectRatio="4:5" reveal />

The photo keeps its values in both themes: light areas take whichever of ink and paper is lighter. Set invert for a negative. Ordered methods update live as you change props; diffusion recomputes in a worker and caches the result, so switching themes only repaints.

Examples

Every method

ProOne photo through Bayer 2, 4 and 8, blue noise, Floyd-Steinberg, Atkinson and Sierra Lite, plus a three tone ordered dither.

States

Loading shows the paper, a missing file says what to do, and a host without CORS headers shows the plain photo instead of an error.

ProLoading, a missing file, four tones, a transparent paper, a negative, a muted ink and a reveal on hover.

Props

PropTypeNotes
src, altstringalt is required: it is the accessible name
algorithm"bayer-2" | "bayer-4" | "bayer-8" | "blue-noise" | "floyd-steinberg" | "atkinson" | "sierra-lite"Default atkinson
pixelSizenumberCSS px per cell, snapped to whole device pixels. Default 2
levelsnumberTones for ordered methods, 2 to 8. Default 2
ink, paperstringAny CSS color or token. paper may be transparent
contrast, brightness, thresholdnumberDefaults 1.1, 0 and 0.5
invertbooleanA negative
revealbooleanOriginal on hover, keyboard focus, or press and hold on touch
aspectRatio, width, heightSet the frame before the image loads, so nothing shifts
maxPixelsnumberDefault 1.5 MP. Lower it for many tiles
renderer"auto" | "webgl" | "2d"Force a path
onStatusChange(status: "loading" | "ready" | "error") => void

EffectImageFrame is exported too: the frame, real image, reveal and error state every image effect shares, for building your own.

Keyboard

KeyAction
TabWith reveal, focus shows the original; leaving hides it

Accessibility

  • The canvas is aria-hidden. The real content always exists: the <img> with your alt sits underneath and is what screen readers announce.
  • Under forced-colors: active the effect hides and the plain image shows with system colors.
  • Under prefers-contrast: more ink and paper snap to the text and canvas tokens, with no mid tones.

Motion

  • The first frame fades in over 200 ms. Reveal crossfades over 150 ms; nothing moves or scales.
  • Under reduced motion only these short fades remain.