Ballpit
An interactive physics ballpit — gravity, walls, and ball-to-ball collisions all simulated live on canvas 2D.
A hand-written physics ballpit on canvas 2D: balls fall under gravity, bounce off the walls, and collide with each other, and moving the mouse pushes the nearby balls aside.
Loading preview…
npx shadcn@latest add https://webberui.com/r/ballpit.jsonPlayground
Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.
40
12
34
900
0.82
<Ballpit />
Installation
npx shadcn@latest add https://webberui.com/r/ballpit.jsonOr, once registries are configured in components.json, install it as @webberui/ballpit.
Usage
The ballpit fills its parent container, so put it inside a bounded box with an explicit height and overflow-hidden:
import { Ballpit } from "@/components/ui/ballpit";
<div className="relative h-[360px] w-full overflow-hidden rounded-xl">
<Ballpit count={48} />
</div>Props
| Prop | Type | Default | Description |
|---|---|---|---|
count | number | 40 | Number of balls |
minSize | number | 12 | Lower bound of the ball radius (px) |
maxSize | number | 34 | Upper bound of the ball radius (px) |
gravity | number | 900 | Gravitational acceleration (px/s²); set 0 for weightless floating |
restitution | number | 0.82 | Fraction of velocity retained after a collision (0~1) |
colors | string[] | 5 built-in colors | Ball palette, applied by cycling through the list |
interactive | boolean | true | Whether the mouse pushes nearby balls away |
pointerRadius | number | 110 | Radius over which the mouse's push acts (px) |
Accessibility
- When the user has "reduce motion" enabled at the system level, the ballpit only lays the balls out at their starting positions and holds still
- The canvas is a purely decorative layer, marked
aria-hiddenand taking no pointer events, so it interferes with neither the keyboard nor a screen reader - The component is self-contained within its parent's dimensions, scaling with the container through a
ResizeObserverand cleaning up the animation loop on teardown