物理標籤堆
標籤像實體一樣掉落堆疊、可抓起拋擲,2D 物理模擬。
pill 標籤從容器上方依序掉落,在底部互相碰撞、推擠、堆疊成一堆;可用滑鼠或觸控抓起拖曳、甩出拋擲(帶速度慣性),被撞到的標籤也會獲得動量。物理引擎為自寫的輕量 2D 膠囊碰撞模擬(重力、反彈、摩擦、rAF 迴圈),零外部物理庫,適合技能牆、興趣標籤等趣味展示。
載入預覽⋯
Playground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
1400
0.3
300
<PhysicsTags />
安裝
npx shadcn@latest add https://webberui.com/r/physics-tags.json或在 components.json 設定 registries 後,改用 @webberui/physics-tags 安裝。
安裝依賴後,從 registry JSON(/r/physics-tags.json 的 files[0].content)複製 physics-tags.tsx 原始碼到你的 components/ui/ 目錄:
npm install motion clsx tailwind-merge使用
import { PhysicsTags } from "@/components/ui/physics-tags";
<PhysicsTags
tags={[
{ label: "React", hue: 200 },
{ label: "TypeScript", hue: 215 },
{ label: "動態設計", hue: 330 },
]}
gravity={1400}
height={340}
/>Props
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
tags | PhysicsTagItem[] | — | 標籤資料陣列,變更時會重新掉落 |
tags[].label | string | — | 標籤顯示文字 |
tags[].hue | number | 依 index 均分色環 | 色相 0–360,決定該標籤配色 |
gravity | number | 1400 | 重力加速度(px/s²) |
restitution | number | 0.3 | 碰撞反彈係數 0–1,越大越彈 |
height | number | 360 | 容器高度(px) |
className | string | — | 透傳到外層容器 |
可及性
- 使用者系統開啟「減少動態效果」時,不啟動任何模擬,標籤以靜態 flex 排列呈現於容器底部
- 物理層的 pill 對輔助科技隱藏(
aria-hidden),另提供sr-only靜態清單供螢幕閱讀器完整朗讀所有標籤 - 容器帶
role="group"與描述性aria-label(含標籤總數) - 支援觸控拖曳(
touch-action: none僅套用在標籤本身,不影響頁面捲動) - 元件捲出視窗外時自動暫停 rAF 迴圈,節省電力與 CPU