---
title: "A pixel grid that breathes, in one canvas loop"
description: "Alex Krasikau's dynamic pixel grid, ported to a themeable canvas component. A field of pixels flickers random opacities inside a circle whose radius pulses on a sine wave."
date: "2026-05-16"
tags: ["canvas", "animation", "generative", "frontend"]
---

I like effects where the code is way simpler than the result. This is one of
them, from [Alex Krasikau](https://x.com/alex_krasikau/status/1895506829129695508):
a grid of pixels that shimmer like static, but contained in a circle that
breathes in and out.

## The whole idea

One canvas, a grid of about 100×100 squares, and an array of opacities. Every
few frames, grab a random slice of cells (~20% of them) and set each to a random
opacity. The rest keep whatever they had. That's already convincing static.

```ts
const updates = Math.floor(count * 0.2);
for (let i = 0; i < updates; i++) {
  const idx = (Math.random() * count) | 0;
  op[idx] = Math.random() * 0.6 + 0.2;
}
```

## The breathing circle

The thing that lifts it from "noise" to "alive" is a mask. A radius oscillates
on a sine wave, and when a cell is chosen it only lights up if it falls inside
that radius. Outside, it snaps to zero:

```ts
const radius = baseR + amp * Math.sin(frame * 0.01);
op[idx] = dx * dx + dy * dy <= radius * radius
  ? Math.random() * 0.6 + 0.2
  : 0;
```

Because the radius grows and shrinks, the static swells out and pulls back in.
No easing curves, no particle system, just `Math.sin` deciding who's allowed to
glow.

## Porting notes

The original draws black pixels on white. I made the color a prop and defaulted
it to a light grey so it works on a dark page, scaled the canvas for device
pixel ratio so the squares don't blur, and had it render a single still frame
when `prefers-reduced-motion` is set. I also pulled the circle test out into a
`shape` prop, so the same pulsing mask can be a `square`, `diamond`, `ring`, or
`full` field. Each one is a one-line distance check (Euclidean for the circle,
Chebyshev for the square, Manhattan for the diamond), which is a tidy reminder
that "which pixels are inside" is just a choice of how you measure distance.

Full credit to [Alex Krasikau](https://x.com/alex_krasikau/status/1895506829129695508).
Grab the component on the [Dynamic Pixel Grid](/components/pixel-grid) page.
