A textbook rock section builds itself, then asks you to read its history.
The section is stored as a history of events: a gneiss basement, layers laid down under a rising sea, tilting, folding, faulting, erosion to an unconformity, and intrusions of basalt dikes or granite plutons. To draw a pixel, the point is carried backwards through every fold, tilt and fault slip, then the deposits, erosion surfaces and intrusions are replayed forwards, so younger events always act on the result of older ones. Each pixel remembers where its rock formed, so the classic map patterns bend with the folds and break at the faults, and contacts, faults and baked contact zones are inked like a textbook figure. When a story ends, letters mark the units and you put the events in order.
Try it. Use the buttons (or the keys D, F, T, X, E and I) to deposit, fold, tilt, fault, erode or intrude a history of your own. Read the rocks (Q) starts the puzzle: click the events from oldest to youngest. New story (N) builds another section.
Paste this into Claude Code, Codex or any coding agent to get a simple version running, then take it wherever you like.
Build an animated geologic cross-section with JavaScript and the HTML canvas element. Put everything in a single index.html file with no libraries or build step, so I can open it directly in a browser.
Start simple:
- Make a canvas that fills the window and stays sharp on high-DPI screens. Use coordinates x from left to right and z from the bottom up.
- Store the geology as a list of events, oldest first: deposit (a stack of horizontal layers, each with a top height and a colour), tilt (a rotation about a point), fold (z shifted by A * sin(x / wavelength)), fault (a dipping plane; points on one side slide along it), erode (everything above a wavy surface becomes air) and intrude (a vertical dike that replaces rock).
- To colour a pixel, first walk the events from newest to oldest and undo each deformation on the point (rotate back, unfold, slide back across the fault), remembering the point at every event. Then replay the events from oldest to newest: a deposit fills only air below its top, an erosion surface turns rock above it into air, and a dike replaces rock inside it. Whatever is left is the pixel's rock.
- Render the whole section into an ImageData at half resolution, scale it up, and play a short scripted history.
Once that works, make it beautiful:
- Use pastel textbook colours and draw patterns in each rock's original position (dots for sandstone, dashes for shale, bricks for limestone), so they bend with the folds and break at the faults.
- Ink the contacts between rocks in dark lines, and draw faults in red.
- Animate each event: let folds grow, faults slip and erosion cut down over a couple of seconds, with a caption that explains what is happening.
Explain the key ideas in short code comments. When you're done, tell me how to open it and suggest three directions I could take it next, such as granite plutons with baked contact zones, a puzzle where I put the events in order, or buttons to add my own events.