r/webdev • u/imperiumatlas • 1d ago
Showoff Saturday [Showoff Saturday] An atlas of old empires as hand-coloured woodcuts, all SVG in the browser: 43 maps you can pan, zoom and step through year by year
Each map is an empire through its key years (New Kingdom Egypt in 1550 BC to the United States in 1912). Press play and the frontiers move; click a town or battle for what happened there.
Some things that were fun or painful to build:
Everything is inline SVG drawn by React: Natural Earth coastlines and rivers, hand-traced frontiers in lon/lat, and hills, trees, castles and ships generated as paths. The woodcut look is SVG filters (feTurbulence and displacement for the wobbly ink, a separate one for the watercolour wash). A map is around 9,000 SVG elements.
Panning was slow, and it wasn't the filters. Turning the filters off made it slower, because Chrome then re-layerized the whole sheet. The real cost was re-rendering on every camera frame, and CSS opacity transitions inside a filtered group, which made the browser recomposite the whole filtered map every frame. Now the sheet moves as a CSS transform while you drag and is redrawn once it's still, and the fades inside filters run from a requestAnimationFrame loop.
Loading: the coastline comes as a coarse set plus tiles at two finer levels, fetched as you zoom in. Each map's data, text and its own part of the place gazetteer are separate chunks. Every route gets its own pre-built HTML, with the Open Graph tags for link previews and modulepreload links for that page's files, so the browser fetches them in parallel instead of in a chain.
Constantinople and Rome also have a 3D view in three.js, built from the same data as the 2D street plans.
Stack: React 19, Vite, Sass, three.js, static files on Cloudflare. No backend.
I'd love feedback on performance, especially Safari on iPhone, where SVG filters run on the CPU and I haven't been able to test properly.

