A quake lifts the seafloor and a tsunami races across a live nautical chart.
The ocean is a grid of real depths (an island arc over a deep trench, a continental shelf, banks and atolls) and the wave obeys the linear shallow-water equations on a staggered grid, so it travels at the square root of g times depth: jetliner speed over the abyss, a crawl on the shelf. Refraction toward shallow water, wrapping around islands and shoaling growth all fall out of that one rule. Every cell records when the wave first passed, and marching squares turns those times into the red 30-minute isochrones of a warning-center chart, while tide gauges on the coasts draw their marigrams.
Try it. Click anywhere in the sea to set off a quake there. Hover to read the depth and wave speed. Tap the title box or press M to switch to a maximum-wave-height map, use the arrow keys or plus and minus to change speed, Space to pause and R for a random quake.
Paste this into Claude Code, Codex or any coding agent to get a simple version running, then take it wherever you like.
Build a tsunami simulation on an ocean map 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 is sharp on high-DPI screens. Behind it, keep a grid of about 300 by 190 cells, each with an ocean depth in metres.
- Generate the depths with a small noise function you write yourself: a basin around 4,000 m deep, a shelf under 200 m along one side, and a few islands (depth below zero is land).
- Use a staggered grid: surface height eta at cell centers, u and v velocities on the faces between cells.
- Each step, update u and v from the slope of eta (u -= g * dt / dx * the difference in eta), then update eta from the depth-weighted flow across the cell's faces. Zero the faces next to land so coasts reflect, and pick dt from the deepest water so the Courant number stays below 0.5.
- On click, add a smooth bump of eta where the visitor clicked.
- Draw the depths once into an offscreen canvas (paper white for deep water, blue for shallow, tan for land). Each frame, draw eta on top through ImageData at grid size scaled up: red for crests, blue for troughs.
Once that works, make it beautiful:
- Record when each cell first sees the wave and draw 30-minute arrival contours with marching squares, like a warning-center map.
- Damp the wave in a band along the edges so it leaves the map.
- Add a few coastal tide gauges that plot their water level over time.
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 a maximum-wave-height map, nonlinear runup onto land, or real bathymetry.