A pop-art background in canvas
Expanding a single-circle motif into a fluid, animated pop-art background with JavaScript and the HTML canvas.
Since the motif of my website is a simple circle, I thought it would be interesting to try and expand upon that idea. So, I decided to create a fluid, dynamic background based on the theme of pop-art using JavaScript and the HTML Canvas.
2026 update The original CodePen embed is being re-hosted — the live demo will return here. In the meantime the write-up below stands on its own.
Please note: This demo might run sluggishly on some older browsers or less powerful hardware configurations due to the number of elements being animated.
The code includes a variable to adjust the radius of each circle. This isn't currently configurable via the control panel in the demo, as changing it requires re-initialising the internal circle matrix – not a hugely complex operation, but one I haven't implemented controls for yet.
However, you can experiment by adjusting the code directly to change the value of the default maxRadius setting (or similar variable name in the source).
If you set the radius to something low (e.g., 3-10 pixels), you'll likely see a performance hit. This seems purely down to the sheer number of circles required to fill the screen per frame. When you add movement and colour shifts on top of that, the demand for constant, smooth animation places some restrictions on what's feasible, especially with older 2D canvas rendering techniques.
I did attempt to build a solution using WebGL rendering techniques at the time, but I found the visual result less satisfactory than rendering the same scene in 2D for this particular pop-art style. Sometimes simpler is better, you know.
I believe significant performance gains are still possible, though. Some ideas include:
Ultimately, it's an experiment in visual generation using basic web tech.
2026 update Two modern routes remove most of the bottleneck described above. First, move the whole simulation off the main thread with OffscreenCanvas plus a Web Worker — the circle matrix and per-frame maths run without blocking scroll or input. Second, for the raw fill-rate problem, a GPU renderer is the real answer now: Pixi v8 ships a WebGPU backend (with a WebGL fallback) and initialises async.
const app = new Application();
await app.init({ preference: 'webgpu', resizeTo: window });
document.body.appendChild(app.canvas);
Thousands of tinted circle sprites batch happily on the GPU, so the tiny-radius case that fell over in 2D canvas becomes cheap.
I help content-rich organisations understand their data and pull it back into one place. Tell me what specific problems you're having and I'll be happy to talk solutions with you.
Tell me what specific problems you’re having and I’ll be happy to talk solutions with you.