Skip to content
← components

Dynamic Pixel Grid

new

A canvas grid of pixels that flicker random opacities inside a sine-pulsing circle — a breathing field of static. Themeable, DPR-crisp, reduced-motion aware. Based on Alex Krasikau.

color
shape

Usage

example.tsx
import { PixelGrid } from "~/components/effects/pixel-grid";
<PixelGrid size={360} color="hsl(0 0% 90%)" />
// other mask shapes: "square" | "diamond" | "ring" | "full"
<PixelGrid shape="diamond" density={0.15} />

How it works

It's a single <canvas> and a loop. The grid is ~100×100 little squares, and each one just stores an opacity. Every few frames, a slice of random cells (about 20%) gets bumped to a random opacity, and the rest hold their value. That alone reads as soft TV static.

The circle is what makes it feel alive. A radius breathes in and out on a Math.sin, and when a cell gets picked, it only lights up if it's inside that radius, otherwise it's snapped to zero. So the field of static swells and contracts. I made it themeable (the original drew black on white; this defaults to light pixels for dark backgrounds), scaled it for device pixel ratio so the squares stay crisp, and had it draw one still frame under prefers-reduced-motion.

pixel-grid.ts
// 100x100 cells; each tick, refresh ~20% of them to a random opacity.
// Inside the pulsing circle they flicker; outside they go dark.
const radius = baseR + amp * Math.sin(frame * 0.01);
if (frame % 5 === 0) {
const updates = Math.floor(count * density);
for (let i = 0; i < updates; i++) {
const x = (Math.random() * grid) | 0;
const y = (Math.random() * grid) | 0;
const dx = x * step + pixelSize / 2 - center;
const dy = y * step + pixelSize / 2 - center;
op[y * grid + x] =
dx * dx + dy * dy <= radius * radius
? Math.random() * 0.6 + 0.2
: 0;
}
}

Props

proptypedefaultdescription
sizenumber360Canvas size in px (square).
pixelSizenumber4Pixel side length.
gapnumber4Gap between pixels.
colorstring"hsl(0 0% 90%)"Any CSS color.
densitynumber0.2Fraction of pixels refreshed each tick.
shape"circle" | "square" | "diamond" | "ring" | "full""circle"Mask the flicker to a sine-pulsing shape.

Original by Alex Krasikau.