Pixelate Region
Cover rectangles of a scene with an opaque mosaic and leave the rest untouched
This filter re-reads the real pixels of the scene it wraps through the experimental html-in-canvas browser API. The preview above shows the true effect in Chrome 149+ with chrome://flags/#canvas-draw-element enabled (nested canvases need 152.0.7944.0+). Every other browser — Safari, Firefox, Chrome without the flag — falls back to a CSS approximation, so the page and your video still play.
Rendering is supported through the CLI, Studio, Lambda and SSR with --gl=angle, or --gl=swangle on a machine without a GPU. Chrome may change or discontinue the API; the fallback is what keeps your composition renderable if that happens.
Installation
$ pnpm dlx shadcn@latest add @remocn/pixelate-regionUsage
PixelateRegion is a wrapper. Give it rectangles in composition coordinates and
everything inside them is resampled into an opaque mosaic — each cell takes the
average of the picture under it — while the rest of the scene passes through
untouched.
import { PixelateRegion } from "@/components/remocn/pixelate-region";
export const MyScene = () => (
<PixelateRegion
regions={[
{ x: 504, y: 332, width: 600, height: 72 },
{ x: 504, y: 444, width: 600, height: 72 },
]}
>
<Scene />
</PixelateRegion>
);Coordinates are in the same units as your composition — the width and height
you gave <Composition> — with the origin at the top left. Read them straight
off the frame you are covering.
The redaction guarantee
This component is a utility, not an effect, and it is built so that failing open is impossible.
Inside a region the output is always opaque. The untouched scene sits on a layer directly beneath the filter's output, so anything less than full coverage would show the original through — which for a mosaic over an API key is not a visual glitch, it is a leak. The mosaic is therefore composited over black and written at full alpha, every frame, on every path.
That includes the browsers that have no html-in-canvas at all. Where every other filter in the pack degrades to an approximation of its look, this one degrades to a plain opaque block over each region: less interesting, exactly as covering.
Passing more regions than can be covered at once throws rather than dropping the
extras, for the same reason — a silently ignored region is a visible secret.
Nest a second PixelateRegion if you need more than eight.
Choosing a cell size
cellSize is the width of one mosaic square in composition units. Text stops
being readable well before it stops being recognisable, so err coarse: a cell
around a third of the cap height of the text you are covering leaves nothing to
reconstruct.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
regions | PixelateRect[] | — | Rectangles to cover, as { x, y, width, height } in composition coordinates from the top-left origin. Up to eight; more throws rather than silently dropping any. |
cellSize | number | 24 | Width of one mosaic square in composition units. Cells are square, and each one is the average of the picture under it rather than a single sample. |
children | React.ReactNode | — | The scene the filter wraps and re-reads every frame. |
Notes
Nothing here animates. The mosaic changes only when the scene under it does, so a region over static content is pixel-identical from frame to frame and a region over a moving dashboard tracks it.
The cell grid is anchored to each region's own top-left corner, so the mosaic starts cleanly at the edge of what you are covering instead of inheriting a grid from the frame.