Rigid-body tops precess, wobble and clash in a steel dish, then topple as they slow.
Each top is a full 3D rigid body with a position, velocity, angular momentum and orientation quaternion, and none of the wobble is scripted. Gravity pulling on the centre of mass while the dish holds up the tip makes a torque that swings the angular momentum around, so a fast top precesses slowly and nods quickly. As friction drains its spin the precession speeds up, and below the critical spin it falls onto its rim and rolls to a stop. Contacts are penalty springs with Coulomb friction at the tip, both edges of the body and the stem, and colliding tops exchange impulses at their rims, where friction trades spin for sideways speed and throws sparks. The dish is ray traced once per resize with an exact ray and paraboloid hit per pixel and a studio reflection.
Try it. Press on the dish, pull back and release to launch a top like a slingshot: a longer pull spins it faster and throws it harder. Right-click or Shift-drag to spin it the other way. Click the view, then press S for slow motion, space for a new pair of tops, R for a fresh battle, or C to clear the dish.
Paste this into Claude Code, Codex or any coding agent to get a simple version running, then take it wherever you like.
Build spinning tops that precess, wobble and fall, 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, stays sharp on high-DPI screens (scale by devicePixelRatio), and resizes with the window.
- Simulate one symmetric top as a rigid body: centre of mass position and velocity, angular momentum L, and its axis direction a. Get the angular velocity from L with two moments of inertia (one along the axis, one across it), and turn the axis by w x a each step.
- Hold the tip on a flat floor with a stiff spring plus damping, and add Coulomb friction at the tip. Gravity plus the floor's push makes a torque; add it to L. Use small time steps (about 0.5 ms).
- Draw it in a simple 3D perspective view as a stack of rings around the axis, and start it spinning fast and slightly tilted. You should see it precess on its own.
- Add a slow drag on the spin so it eventually wobbles and falls.
Once that works, make it beautiful:
- Colour the body in alternating sectors so you can see it spin, blending them together when it spins too fast to follow.
- Put several tops in a shallow dish and let them collide: an impulse along the line of centres, plus friction at the rims that trades spin for sideways speed. Throw sparks at each clash.
- Let me launch tops by pressing, pulling back and releasing, with the pull setting the spin.
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 tippe top that flips upside down, plotting the axis tip to show nutation loops, or measuring the critical spin speed.