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

推荐订阅源

A
Arctic Wolf
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Google Online Security Blog
Google Online Security Blog
Help Net Security
Help Net Security
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
T
The Exploit Database - CXSecurity.com
Application and Cybersecurity Blog
Application and Cybersecurity Blog
S
Security Affairs
N
News and Events Feed by Topic
Forbes - Security
Forbes - Security
月光博客
月光博客
博客园 - Franky
The GitHub Blog
The GitHub Blog
O
OpenAI News
The Cloudflare Blog
Google DeepMind News
Google DeepMind News
P
Privacy & Cybersecurity Law Blog
WordPress大学
WordPress大学
H
Help Net Security
Apple Machine Learning Research
Apple Machine Learning Research
V
Visual Studio Blog
爱范儿
爱范儿
S
Secure Thoughts
T
The Blog of Author Tim Ferriss
SecWiki News
SecWiki News
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
J
Java Code Geeks
阮一峰的网络日志
阮一峰的网络日志
宝玉的分享
宝玉的分享
博客园_首页
Cisco Talos Blog
Cisco Talos Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
C
Cisco Blogs
博客园 - 三生石上(FineUI控件)
Hacker News: Ask HN
Hacker News: Ask HN
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
人人都是产品经理
人人都是产品经理
腾讯CDC
Know Your Adversary
Know Your Adversary
P
Proofpoint News Feed
云风的 BLOG
云风的 BLOG
The Last Watchdog
The Last Watchdog
博客园 - 叶小钗
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Hugging Face - Blog
Hugging Face - Blog
PCI Perspectives
PCI Perspectives
罗磊的独立博客
有赞技术团队
有赞技术团队
B
Blog RSS Feed
L
LINUX DO - 最新话题

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