Lab · experiment, not a feature
The same renderer, with no map
If a general animated-storytelling renderer is GeoStory without the geography, then most of it may already be built. This page tests that instead of estimating it. Turn the basemap off and the exporter’s own frame renderer keeps drawing everything else — so what is left on the canvas is the measurement.
The voice is the browser’s own speech synthesis, driven by the same hook the player uses, and it only starts once you press Play — browsers refuse to speak before a visitor has interacted with the page. It is not the ElevenLabs voice the export uses, so judge the timing here, not the delivery. A line longer than its scene is cut at the boundary rather than allowed to run over, which is a true report of the document’s declared durations.
How the switch works
No rendering code was changed or added for this. The frame renderer resolves its tile source from a map passed in as an argument, so an empty map suppresses the basemap and the locator inset while leaving every other draw call intact.
// lib/geostory/raster.ts
const source = basemap ? tiles.get(basemap.id) : undefined
if (camera && source) {
await drawBasemap(context, source, camera, band.width, band.height)
}
// ...and the reason the rest still works: the projection is an argument.
const place = (lng: number, lat: number) =>
toScreen(lng, lat, camera, band.width, band.height)
drawAnnotations(context, annotations, windows, seconds, place, scale, ...)
drawFlow(context, annotations, windows, seconds, place, scale)
drawAnnotationLabels(context, annotations, windows, seconds, place, scale, ...)None of the shape, line or label code knows what a map is. It asks place(x, y) for pixels and draws. Replacing that one closure with a canvas-space mapping is what a Motion profile would actually require of the renderer.
Already there
Images, in a corner or filling the frame
A picture attached with media_ids takes that scene's window. fit: cover fills the band and crops, so a scene can simply BE a picture while keeping its title, caption and narration - no new kind of scene, and no new timing rules.
Charts
A chart kind: bars or a line, growing from a zero baseline as they arrive. Measured against its own data, the bars come out at 0.005, 0.218, 0.519 and 1.000 of the tallest.
Label-aware framing
The camera measures the words as well as the shapes and gives way to them, so the safe area is 0.08 because that is the margin a frame wants - not because labels were being clipped at anything smaller.
Narrated video export
A canvas document renders to MP4 through the same pipeline a geostory uses, with no Motion-specific code - and with a generated voice, the scenes stretch to fit it rather than the sentences being cut.
Themes
A root theme block: eleven colours, a font stack and the emphasis scale, with midnight, paper and editorial presets. The same deck renders light or dark with its layout unchanged.
Staggered arrival
A scene saying stagger: 0.3 sequences its elements in the order it lists them, so inserting one does not mean renumbering the rest.
Per-element animation
enter and exit, each with a delay and a duration: fade, rise, fall, left, right and a typewriter that reveals a label character by character.
Canvas addressing
An annotation can declare space: canvas and be positioned in percentages of the frame, with no camera involved. The first story in the list has no places and no basemaps at all, and draws.
A text kind
Text no longer has to hang off a shape. kind: text is a label on its own, positioned with pos: [x, y].
Content framing
A document with no basemap frames what the scene draws rather than a declared place. Scene 4 of the presentation went from 41.6% of the frame width to 61.1%, with nothing clipped.
No map, no map furniture
The scale bar, north arrow, locator inset and place-name sub-heading are suppressed when no basemap is drawn - they describe ground that is not on the frame.
A type scale
Labels take an emphasis - display, title, body, caption - so the number at the centre of a slide no longer reads as loudly as the six things around it.
Scene timeline
Document-absolute timing, scene lengths, delays, derived durations. Subject-agnostic already.
Narration sync
TTS, measured durations and the piecewise retime that moves media and annotations with the scenes.
Title block and legend
Kicker, numbered scene title, dek, legend rows and a scene counter, all read from the document.
Captions
Word wrapping, a slab behind the words and a half-second fade at each end.
Shapes and labels
Circles, markers, lines, polygons, leader callouts and a separate label pass, all drawn through an injected projection.
Timed images
Media windows with fades, drawn over the canvas at a declared position and width.
Video export
WebCodecs and mediabunny, rendering faster than realtime to MP4 in the browser.
Not there at all
Layout
Elements are still positioned one coordinate at a time. There is no center, no stack and no grid, so a column of text is three coordinates that have to agree with each other.
Per-element animation
enter, exit, delay, easing, stagger. Today the only tweened values are the camera and a half-second opacity fade.
Text animation
No typewriter, no kinetic type, no per-word or per-line reveal.
Charts
Nothing. No axes, no scales, no animated series.
The second test: a document with no geography
Suppressing the basemap still leaves a story about real places. The harder question is whether the renderer can draw something with no geography in it at all, so the first story in the list above is a product presentation: five scenes, no basemap, one place used by every scene so the camera never moves.
It needed no renderer changes. Every annotation is addressed in longitude and latitude, and Web Mercator is very nearly linear at the equator — cos(0) = 1 — so a box of 3.2° × 1.8° centred on [0, 0] is a 16:9 Cartesian canvas the existing projection draws correctly. Markers become nodes, a four-corner polygon becomes a box, and an animated line becomes a flowing connector.
It works, and it is too small. On the first authoring pass the whole diagram occupied 22.7% of the frame width and under 1% of the map band in ink. Widening every coordinate by hand took it to 41.6% and 3.6%. That arithmetic is the finding: the camera frames the declared place bounds with a 20% padding meant for maps, not the content, so filling a frame is manual and easy to get wrong. Geography leaks too — the scale bar, the north arrow and the place name as a sub-heading all appear on a slide that has no location.
What this says
The infrastructure is largely built and the content model is entirely absent. Timeline, narration, captions, chrome and export are subject-agnostic today; elements, layout, per-element animation and type are not started. That is a far better starting position than nothing, and it is not most of the way there.
One thing the probe makes plain that no diagram would: with the map gone, the frame has nothing to lean on. A basemap is interesting on its own; a flat background is not. The hard part of Motion is the type, layout and motion defaults — a design problem, not an engineering one.
Related: how a document works · the player · the Gazette