Hundreds of colorful balls tumble, stack and bounce off each other.
A compact rigid-body engine for circles: gravity, sub-stepped integration, wall bounces, and pairwise collision response that separates overlapping balls and exchanges momentum along the collision normal. A spatial hash keeps collision checks fast. Every so often the floor tilts so the pile flows.
Try it. Grab a ball and throw it. Click empty space to drop more balls. Press R to reset.
Paste this into Claude Code, Codex or any coding agent to get a simple version running, then take it wherever you like.
Build a ball pit physics toy 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. Paint it a soft light background.
- Create about 300 balls with random radii between 8 and 16 pixels and bright colors, dropped in from above the screen. Store positions and velocities in plain arrays.
- Each frame, split the time step into 6 sub-steps. In each one, add gravity, move every ball, and bounce it off the walls and floor with a restitution of about 0.4.
- Resolve collisions between every pair of overlapping balls: push them apart along the line between their centers in proportion to their mass, then apply an impulse along that normal so they trade momentum instead of passing through each other.
- Animate with requestAnimationFrame and draw each ball as a filled circle.
Once that works, make it beautiful and fast:
- Replace the all-pairs check with a spatial hash: a uniform grid with cells the size of the largest ball, so each ball only tests the balls in its own and the 8 neighboring cells.
- Pre-render one glossy ball per color into a small offscreen canvas (a radial gradient with a white highlight and a darker rim) and draw balls with drawImage.
- Let me grab a ball with the mouse and throw it using the pointer's recent velocity. Clicking empty space drops a handful of new balls.
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 floor that tilts back and forth, balls of different weights that sort themselves, or tilting gravity with the phone's accelerometer.