Pixel image reveal
An image that resolves from a coarse pixel mosaic to sharp, in a few stepped frames. One <canvas> over a normal <img> (so the image keeps its alt text, lazy loading and SEO); the canvas only draws and never reads pixels, so cross-origin images work. With reduced motion the image just appears.
import { PixelImageReveal } from "pixelbits/image-reveal";
const sunset = `data:image/svg+xml;utf8,${encodeURIComponent(
'<svg xmlns="http://www.w3.org/2000/svg" width="400" height="500" viewBox="0 0 400 500"><defs><linearGradient id="g" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#1d1a2b"/><stop offset=".55" stop-color="#7a4a3a"/><stop offset="1" stop-color="#e2a36a"/></linearGradient></defs><rect width="400" height="500" fill="url(#g)"/><circle cx="265" cy="260" r="70" fill="#f6d39a"/><path d="M0 330 Q100 280 200 335 T400 320 V500 H0Z" fill="#3b2730"/><path d="M0 400 Q140 360 260 405 T400 395 V500 H0Z" fill="#120d11"/></svg>',
)}`;
export default function Demo() {
return (
<div className="grid w-full max-w-md grid-cols-2 gap-4">
<PixelImageReveal
src={sunset}
alt="Sunset over hills"
wrapperClassName="aspect-4/5 rounded-pb-sm"
/>
<PixelImageReveal
src={sunset}
alt="Sunset, revealed on hover"
trigger="hover"
wrapperClassName="aspect-4/5 rounded-pb-sm"
/>
</div>
);
}Installation
import { PixelImageReveal } from "pixelbits/image-reveal";npx shadcn add https://pixelbits.ali-moradi-develop.com/r/image-reveal.jsonAPI
<PixelImageReveal>
An image that resolves from a coarse pixel mosaic to sharp, in a few stepped frames. One <canvas> over a normal <img> (so the image keeps its alt text, lazy loading and SEO); the canvas only draws and never reads pixels, so cross-origin images work. With reduced motion the image just appears.
<PixelImageReveal src="/work/noir.jpg" alt="Atelier Noir home page" wrapperClassName="aspect-4/5" />| Prop | Type | Default | Description |
|---|---|---|---|
| src* | string | — | Image URL. |
| alt* | string | — | Alternative text, as for any image (empty for decorative ones). |
| trigger | "view" | "hover" | "view" | When the reveal runs: when the image scrolls into view, or on hover and focus of the image's container (it then goes back to the mosaic). |
| steps | number[] | [32, 16, 8, 4] | Block sizes in px, from coarse to fine, before the sharp image. |
| duration | number | 600 | Total duration of the reveal in ms. |
| wrapperClassName | string | — | Classes for the wrapper (size it here; the image covers it). |
Also accepts every prop of ImgHTMLAttributes<HTMLImageElement>.