Confetti Feedback
自製粒子彩帶慶祝:從原點噴發、各帶初速/重力/旋轉/飄移,rAF 更新落地後回收。
載入預覽⋯
Playground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
50
<ConfettiFeedback />
安裝
npx shadcn@latest add https://webberui.com/r/confetti-feedback.json或在 components.json 設定 registries 後,改用 @webberui/confetti-feedback 安裝。
安裝依賴後,從 registry JSON(/r/confetti-feedback.json 的 files[0].content)複製 confetti-feedback.tsx 原始碼到你的 components/ui/ 目錄:
npm install motion clsx tailwind-merge使用
最簡單的用法是 ConfettiButton,點擊時會從按鈕中心噴發彩帶並照常執行 onClick:
import { ConfettiButton } from "@/components/ui/confetti-feedback";
<ConfettiButton onClick={() => save()}>慶祝一下 🎉</ConfettiButton>需要在任意時機、從任意座標噴發時,改用 useConfetti hook。它回傳 fire 與必須渲染到畫面上的 confetti 節點:
import { useConfetti } from "@/components/ui/confetti-feedback";
function CheckoutDone() {
const { fire, confetti } = useConfetti();
return (
<>
<button
onClick={(e) => {
const r = e.currentTarget.getBoundingClientRect();
fire({ x: r.left + r.width / 2, y: r.top + r.height / 2 });
}}
>
完成
</button>
{confetti}
</>
);
}fire(origin?, options?) 的 origin 為視口座標(省略時預設畫面上方中央),options 可帶 particleCount 與 colors。
Props
ConfettiButton
透傳所有原生 button 屬性,另外提供:
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
particleCount | number | 50 | 每次噴發的粒子數,夾在 0 ~ 80 之間 |
colors | string[] | 內建七色 | 彩帶配色候選,逐片隨機取用 |
onClick | (e) => void | — | 噴發後照常執行 |
className | string | — | 附加到按鈕的樣式 |
useConfetti()
| 回傳 | 型別 | 說明 |
|---|---|---|
fire | (origin?, options?) => void | 觸發一批噴發;origin 為視口座標 { x, y } |
confetti | React.ReactNode | 必須渲染的節點,內部以 createPortal 疊到最上層 |
options 支援 particleCount(上限 80)與 colors。
細節與可及性
- 粒子為 DOM 小色塊,rAF 逐幀更新
transform(位移、旋轉、飄移擺動),不觸發 React re-render - 每片彩帶帶隨機初速與重力,落到視口底部或超過最長存活時間即回收;整批清空後自動卸載
dt有上限,分頁切回或掉幀時不會讓粒子瞬移- 單批粒子上限 80,連點時只保留最新幾批,較舊批次會卸載並停掉其 rAF
- 卸載時
cancelAnimationFrame清理,不會在卸載後更新 - 純裝飾層帶
aria-hidden且pointer-events-none,不干擾指標與輔助科技 - 使用者系統開啟「減少動態效果」時完全不噴發,但按鈕的
onClick動作仍會執行