Ryan Kalagin

Introducing Ummah Canvas

A shared canvas, two thousand pixels across, that anyone can add to one pixel at a time.

By Ryan Kalagin,

Ummah Canvas is one big shared picture. Everyone who visits sees the same canvas, and anyone who signs in can add to it one pixel at a time, with a short wait between each pixel. Whatever appears is made by whoever turns up.

It was made with Islamic geometric patterns and calligraphy in mind. Those traditions are built on grids and repeated shapes, so they suit pixels well. The thirty-two colours lean towards the glazes of traditional tilework, such as Iznik blues and the greens and ochres of zellige, while still covering a full range. You’re welcome to make whatever you like. The main rule is to be kind to other people and to look after what they’ve made.

The idea comes from shared canvases like r/place and PixelCanvas, which I’ve always enjoyed watching. This is my own small version of one, and I learned a great deal making it.

Making it live

The part I found most interesting was making it feel live. When someone places a pixel, it should appear on everyone else’s screen straight away, not the next time they refresh the page.

To do that, each browser keeps a connection open to the server using WebSockets. A normal web page asks the server for something, gets an answer, and the conversation ends. A WebSocket stays open, so the server can send updates the moment they happen. When you place a pixel, your browser sends it along that connection. The server checks it, updates its own copy of the canvas, and passes the change on to everyone else who is connected, normally within a fraction of a second. Each message is tiny, little more than a position and a colour, so even with lots of people drawing at once there isn’t much data moving around.

The server checks that each pixel is on the canvas, that the colour is one of the thirty-two, and that you’ve waited long enough since your last one. That wait is ten seconds at the moment, and it’s checked on the server and tied to your account rather than to your browser. If it were only checked in the browser, refreshing the page would reset it, and the whole idea of drawing slowly together would fall apart.

The canvas itself is held in memory as four million single bytes, one for each pixel, with each byte saying which of the thirty-two colours that pixel is. That comes to about four megabytes, which is small enough to keep the whole thing in memory at once.

Keeping it safe

A canvas like this has to survive the server restarting, and the occasional person who wants to spoil things for others.

Behind the server is a PostgreSQL database. Every change is written to a log as it happens, and the whole canvas is saved as a compressed snapshot at regular intervals: a working copy every thirty seconds, and a copy that’s kept every five minutes. While most of the canvas is still empty, four million pixels compress down to just a few kilobytes. If the server restarts, it loads the latest snapshot and replays anything in the log since, so nothing is lost.

The same history makes moderation possible. If an area gets spoiled, it can be rewound to how it looked at an earlier time without touching anything outside it. And if one person has been drawing over other people’s work, their changes can be taken out by rebuilding that area from an earlier snapshot and replaying everyone else’s changes except theirs. I didn’t see this at first, but simply reversing that one person’s pixels would also have wiped out any repairs other people had already made on top. Replaying everyone else keeps those repairs.

Signing in is done with Google, which means the limits apply to a person rather than to a browser tab. You don’t need to sign in just to look.

What I learned

A lot of this I learned by getting it wrong first. One example: the server was meant to save the canvas one last time whenever it was restarted, so that an update would never lose anything. That worked on my computer but quietly didn’t on the hosting platform, because the signal to stop was going to the tool that launched the program rather than to the program itself. The fix turned out to be one line of configuration. Finding it took rather longer.

Mistakes like that are why the project now has several hundred automated checks, including some that start a real server, open two browser windows side by side, and make sure what one person draws really does appear for the other.

For anyone curious about the setup, the server is Node.js with Express, the live connections use the ws library, the database is PostgreSQL, and it’s hosted on Railway, which rebuilds the site automatically whenever I push a change to GitHub. There’s no front-end framework; the page you draw on is a single HTML file.

Ummah Canvas is free at ummahcanvas.com. If you stop by and add something, I hope you enjoy it, and please look after what others have made.