Ballpit
可互動的物理彈跳球池,重力、牆面與球球碰撞皆以 canvas 2D 即時模擬。
以 canvas 2D 手寫的物理球池:重力落下、牆面反彈、球與球互相碰撞,滑鼠移動還能撥開附近的球。
載入預覽⋯
Playground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
40
12
34
900
0.82
<Ballpit />
安裝
npx shadcn@latest add https://webberui.com/r/ballpit.json或在 components.json 設定 registries 後,改用 @webberui/ballpit 安裝。
安裝依賴後,從 registry JSON(/r/ballpit.json 的 files[0].content)複製 ballpit.tsx 原始碼到你的 components/ui/ 目錄:
npm install motion clsx tailwind-merge使用
球池會填滿父容器,請放進一個有明確高度且 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 | 型別 | 預設值 | 說明 |
|---|---|---|---|
count | number | 40 | 球的數量 |
minSize | number | 12 | 球半徑下限(px) |
maxSize | number | 34 | 球半徑上限(px) |
gravity | number | 900 | 重力加速度(px/s²);設 0 則無重力漂浮 |
restitution | number | 0.82 | 碰撞後速度保留比例(0~1) |
colors | string[] | 內建 5 色 | 球體配色,循環套用 |
interactive | boolean | true | 滑鼠是否推開附近球體 |
pointerRadius | number | 110 | 滑鼠推力作用半徑(px) |
可及性
- 使用者系統開啟「減少動態效果」時,球池只擺好初始位置並靜止不動
- canvas 為純裝飾層,標記
aria-hidden且不吃指標事件,不干擾鍵盤與螢幕閱讀器 - 元件自足於父容器尺寸,透過
ResizeObserver隨容器縮放,離場時會清理動畫迴圈