Components / Animations / Bitmap Image
Bitmap Image
An image thresholded into newsprint. The source is box-filtered down to the cell grid first, so every cell has a real antialiased grey before it is dithered — which is the difference between newsprint and broken JPEG.
Usage
import BitmapImage from '@/components/bitmap-image'
<BitmapImage
src={photo}
cell={4}
dither="floyd"
fit="cover"
/>Installation
npx shadcn@latest add https://morphiq.prathampatel.design/r/bitmap-image.jsonModel
(v) => String(v.dither).startsWith("bayer") ? "out = level(tone + (M(x, y)/n² − ½)/levels)" : v.dither === "none" ? "out = round(tone · (levels − 1)) / (levels − 1)" : "e = tone − out; e spreads to unvisited neighbours by the kernel’s weights"M the Bayer matrix, n its size · error diffusion carries each cell’s rounding error forward, so tone is conserved over area
Props
| Property | Type | Default | Description |
|---|---|---|---|
cell | number | 4 | Pixels per cell. Smaller is finer and costs more per frame. |
levels | number | 2 | Tone steps. 2 is one-bit; higher posterises. |
dither | DitherKernel | 'floyd' | — |
ditherAmount | number | 1 | 0 passes the tone through untouched, 1 applies the kernel in full. |
serpentine | boolean | true | Alternate scan direction. Error-diffusion kernels only. |
contrast | number | 1.1 | — |
brightness | number | 0 | — |
invert | boolean | false | — |
warp | number | 0 | Flow-field shear, in cells. |
cursorRadius | number | 160 | Reach of the pointer's influence, in px. |
cursorStrength | number | 0 | Outward push at the centre of that reach, in px. |
cursorLift | number | 0 | Luminance added at the centre of that reach. |
color | string | '#e8e4dc' | — |
background | string | null | '#0a0b0e' | null renders transparent. |
paused | boolean | false | Stops the frame loop without unmounting. |
respectReducedMotion | boolean | true | Honour prefers-reduced-motion, and keep honouring it if it changes. |
fullscreen | boolean | false | Position the field to the viewport rather than its container. |
src | string | — | — |
alt | string | '' | As on <img>: describe the picture, or leave empty to mark it decorative. |
fit | 'cover' | 'contain' | 'fill' | 'cover' | — |
focusX | number | 0.5 | Crop anchor, 0..1. |
focusY | number | 0.5 | — |
onStatus | (status: 'ready' | 'empty' | 'tainted') => void | — | — |