惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

P
Palo Alto Networks Blog
N
Netflix TechBlog - Medium
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
小众软件
小众软件
WordPress大学
WordPress大学
宝玉的分享
宝玉的分享
B
Blog
MyScale Blog
MyScale Blog
Microsoft Security Blog
Microsoft Security Blog
aimingoo的专栏
aimingoo的专栏
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Hugging Face - Blog
Hugging Face - Blog
S
Schneier on Security
Project Zero
Project Zero
T
Tenable Blog
T
Tor Project blog
U
Unit 42
G
GRAHAM CLULEY
N
News and Events Feed by Topic
P
Proofpoint News Feed
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Y
Y Combinator Blog
C
Cybersecurity and Infrastructure Security Agency CISA
腾讯CDC
博客园 - 叶小钗
M
MIT News - Artificial intelligence
Vercel News
Vercel News
T
Threat Research - Cisco Blogs
D
Darknet – Hacking Tools, Hacker News & Cyber Security
T
The Exploit Database - CXSecurity.com
P
Privacy & Cybersecurity Law Blog
I
Intezer
博客园 - 聂微东
SecWiki News
SecWiki News
Scott Helme
Scott Helme
C
Cyber Attacks, Cyber Crime and Cyber Security
IT之家
IT之家
量子位
S
Secure Thoughts
The Cloudflare Blog
博客园 - 司徒正美
Know Your Adversary
Know Your Adversary
Hacker News: Ask HN
Hacker News: Ask HN
V
Vulnerabilities – Threatpost
Simon Willison's Weblog
Simon Willison's Weblog
N
News | PayPal Newsroom
C
Check Point Blog
Spread Privacy
Spread Privacy
C
CXSECURITY Database RSS Feed - CXSecurity.com
Cyberwarzone
Cyberwarzone

Home on Alex Plescan

Just for fun: animating a mosaic of 90s GIFs Two computers, one monitor, zero fiddling Placeholder names should be bad and unique Rebuilding this site Okay, I really like WezTerm GNU Parallel, where have you been all my life? Timeseries with PostgreSQL Easy SVG sparklines Using Declarative Shadow DOM to embed HTML emails on a web page Selling SaaS on Gumroad PDF: The Conjoined Triangles of Success Deploying Metabase to Fly.io The ".x" Files Xcode 8 managed signing: adding new device UUIDs to a provisioning profile Emojify your Wi-Fi (Netgear R6300 edition) How to use the San Francisco Mono typeface before macOS Sierra is released Disabling App Transport Security in your development environment Swift: A nicer way to tell if your app is running in Debug mode Development environment config overrides in Jekyll Setting up SwiftLint on Travis CI
bigdraw: I made a collaborative drawing site
2026-07-07 · via Home on Alex Plescan

Here’s a little thing I’ve been building over the past few weeks: bigdraw.party.

It’s a big grid made up of little drawings that anyone can add to. No logins required (or drawing skills, for that matter):

screenshot of the bigdraw.party drawing grid

To add to the grid, claim a free tile and draw using basic tools (think MS Paint). Here are some examples closer up (click to jump to them in bigdraw):

drawing of toast with the words I love toast drawing of a red guitar under the sun drawing of a ringed yellow planet in space

Since every drawing gets its own permanent spot, strangers can extend them, surround them, or find other ways to respond - which turns the grid into a shared place. Or you can wander far away and draw something in a lonesome spot, to be stumbled on by someone later… or never.

Some of my favourite times on the internet have been on websites that make you feel connected with complete strangers, and I’m hoping to recreate some of that magic with bigdraw.

Building it, in a nutshell

Building this came with some fun learnings and challenges. I’ll run through some of the interesting parts at a high level, but will leave deep dives for future more focused posts.

Backend

The backend is a Go service with a SQLite store. It’s responsible for serving up the images, the grid metadata, and for accepting new submissions.

You can zoom out pretty far in bigdraw, and that’s where a lot of the fun starts… on my Macbook Air if I zoom as far as I can, I see ~45,000 tiles in my viewport. And that’s on a small screen. The bigger the screen, the more tiles that can fit.

Here’s a viewport filled with test images so you can see what I mean. Each one of those little squares represents a 700x700px drawing. Watch the video to see a zoom from far to near:

This zoomed out view makes the grid feel more like a place and less like an image gallery. From the high vantage point you can see clusters forming, empty regions waiting to be claimed, and where people are drawing at any given time.

But if each tile was represented as an image, that’d be 45,000 images per screen - I don’t know about your connection speed but mine can’t handle that.

To make this performant I use tile maps (as seen in your favourite map app) and construct a tile pyramid at increasing powers of two. So when you’re zoomed right in, one image is one tile, zoom out a bit further and one image becomes 4 tiles, then 16, 64… up to 16,384 tiles per image at the farthest zoom level.

Then there’s the metadata associated with each tile which helps answer questions like “is the tile being drawn on right now?” This starts from a fine level of detail when you’re zoomed in and gets coarser as you zoom out. The coarse representation is a bitset where 0 = unclaimed, 1 = claimed. For 45,000 tiles that’s 45,000 bits = 5.6kB to represent claims on all visible tiles. This kind of representation compresses easily, so the net result is a much smaller payload pushed over the wire.

The tiles and metadata are returned in chunks and cached at the edge (Cloudflare) with a very short TTL. This means that the server doesn’t have to get hammered too hard if multiple requests are coming in for the same chunk at the same time. The tradeoff is that the viewport can lag behind the changes being made by a few seconds, but this is well worth it considering the implementation simplicity it leads to.

Frontend

The frontend is plain old JavaScript using native web APIs. The grid and drawings get rendered onto a 2D Canvas, which has got two main modes:

Panning mode, where you can zoom and pan around the grid. For this, images are loaded on the fly and smoothly interpolated between zoom levels. Per the video above you can start from the furthest away spot and zoom in to the closest - without perceiving that the underlying images are being swapped out.

The tiled web maps also lend themselves to high DPI screens, since for any given viewport if we want a higher pixel density image, we can just request the finer zoom level. This does lead to more requests and processing on high DPI screens, but typically those screens are attached to faster computers anyway so the actual impact is imperceptible. I tested bigdraw on the cheapest phone I could find at my local Officeworks and it performed well.

And then there’s drawing mode, where you can draw on your tile :) This was heavily inspired by the JSPaint reimplementation of MS Paint, as I wanted to capture the feel of oldschool digital brushes.

Your brush dabs (excuse me while I show off my newly learned painting terminology) are drawn to a 700x700px OffscreenCanvas that’s then projected onto the visible canvas. Keeping two canvases in memory and in sync is inefficient, however it simplifies implementation a lot: if you pan and zoom while drawing, then the offscreen canvas can be projected at a different coordinate/dimension without needing to do tricky maths, and then when you submit it the output becomes a 1:1 mapping of the canvas pixels to the final image.

There are also some basic UI controls in bigdraw (toolbars, modals, etc) which manage DOM element lifecycles. This part of the codebase is particularly distressing to look at since it writes innerHTML directly and binds to DOM nodes manually, but so far this procedural approach has worked, and I’m not convinced it’s time to wrap it up in a framework just yet. Especially considering that the plain JavaScript approach produces a 47kB gzipped bundle for the entire site, whereas React + React DOM on their own weigh in at 60kB.

Conclusion

I’ll probably expand on the implementation details in future posts - there’s more to talk about both depth and breadth wise. Let me know if there’s something in particular you’re interested in learning more about!

Thanks for reading, and I hope to see you on bigdraw.party.

drawing saying thanks for drawing with a flower