WebberUI

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.jsonfiles[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 可帶 particleCountcolors

Props

ConfettiButton

透傳所有原生 button 屬性,另外提供:

Prop型別預設值說明
particleCountnumber50每次噴發的粒子數,夾在 0 ~ 80 之間
colorsstring[]內建七色彩帶配色候選,逐片隨機取用
onClick(e) => void噴發後照常執行
classNamestring附加到按鈕的樣式

useConfetti()

回傳型別說明
fire(origin?, options?) => void觸發一批噴發;origin 為視口座標 { x, y }
confettiReact.ReactNode必須渲染的節點,內部以 createPortal 疊到最上層

options 支援 particleCount(上限 80)與 colors

細節與可及性

  • 粒子為 DOM 小色塊,rAF 逐幀更新 transform(位移、旋轉、飄移擺動),不觸發 React re-render
  • 每片彩帶帶隨機初速與重力,落到視口底部或超過最長存活時間即回收;整批清空後自動卸載
  • dt 有上限,分頁切回或掉幀時不會讓粒子瞬移
  • 單批粒子上限 80,連點時只保留最新幾批,較舊批次會卸載並停掉其 rAF
  • 卸載時 cancelAnimationFrame 清理,不會在卸載後更新
  • 純裝飾層帶 aria-hiddenpointer-events-none,不干擾指標與輔助科技
  • 使用者系統開啟「減少動態效果」時完全不噴發,但按鈕的 onClick 動作仍會執行

On this page