Circular Progress
動畫百分比環形進度/量表,支援漸層、gauge 弧度與計數揭示。
以 SVG 環形呈現進度,弧線與中央數字由單一動畫節奏同步推進,支援完整環或量表 gauge。
把這個效果裝進你的專案
在專案資料夾執行指令,CLI 會加入原始碼與依賴套件,再依下方使用範例引用元件。
npx webberui@latest add circular-progressCircular Progress 是用 React、SVG 與 Motion 做的圓形進度條(環形進度、圓環百分比)元件:進度弧與中央數字由同一個動畫值驅動,支援漸層色、端點圓頭與柔光,把 arc 調小於 360 就能當成半圓或 270 度的量表。
Playground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
<CircularProgress/>
完整範例包含預覽的排版與資料。先安裝元件,再把範例檔貼入你的專案。
適用情境
- 上傳、匯出、批次處理這類有明確百分比的任務進度
- 帳號設定或新手引導的「完成度」指標
- 方案用量、儲存空間、配額使用率的摘要卡片
- 儀表板上的 KPI 達成率
- 不適合:需要刻度、指針與色段分區的儀表,改用 Gauge Meter
安裝
npx webberui@latest add https://webberui.com/r/circular-progress.json或在 components.json 設定 registries 後,改用 @webberui/circular-progress 安裝。
使用
import { CircularProgress } from "@/components/ui/circular-progress";
<CircularProgress value={72} />;做成量表 gauge:把 arc 設成小於 360,再用 startAngle 對齊開口方向。
<CircularProgress value={86} arc={270} startAngle={135} />;範例
隨上傳進度更新
value 改變時,弧線與數字會從目前的值補間到新的值,不會從 0 重來,可以直接接進度事件。
"use client";
import * as React from "react";
import { CircularProgress } from "@/components/ui/circular-progress";
export function UploadProgress({ file }: { file: File }) {
const [percent, setPercent] = React.useState(0);
React.useEffect(() => {
const xhr = new XMLHttpRequest();
xhr.upload.onprogress = (e) => {
if (e.lengthComputable) setPercent((e.loaded / e.total) * 100);
};
xhr.open("POST", "/api/upload");
xhr.send(file);
return () => xhr.abort();
}, [file]);
return <CircularProgress value={percent} size={120} duration={0.4} decimals={0} />;
}中央改放自訂內容
傳入 children 會取代預設的百分比數字,適合顯示「3 / 5 步」這類非百分比資訊;value 仍需換算成 0 到 100。
<CircularProgress value={(3 / 5) * 100} size={140} strokeWidth={10}>
<span className="text-2xl font-semibold">3 / 5</span>
<span className="text-xs text-neutral-500">設定步驟</span>
</CircularProgress>單色加柔光的儲存空間用量
color 傳字串就是單色,glow 會用同一個顏色加上 drop-shadow 柔光;trackColor 自訂底軌。
<CircularProgress
value={82.4}
decimals={1}
color="#f97316"
trackColor="#fed7aa"
glow
rounded={false}
/>Props
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
value | number | — | 進度百分比(0 ~ 100) |
size | number | 160 | 元件邊長(px) |
strokeWidth | number | 12 | 環的線寬(px) |
color | string | string[] | 青靛洋紅漸層 | 單色字串或沿弧線的漸層陣列 |
trackColor | string | currentColor 低透明 | 底軌顏色 |
arc | number | 360 | 弧線總跨度(度),小於 360 即為量表 |
startAngle | number | -90 | 起始角度(度),-90 為正上方 |
duration | number | 1.2 | 進場動畫時長(秒) |
delay | number | 0 | 進場前延遲(秒) |
rounded | boolean | true | 端點是否為圓頭 |
showValue | boolean | true | 是否顯示中央百分比數字 |
decimals | number | 0 | 數字小數位數 |
suffix | string | "%" | 數字後綴 |
glow | boolean | false | 為進度弧加上同色柔光 |
children | ReactNode | — | 中央自訂內容,覆蓋預設數字 |
可及性
- 使用者系統開啟「減少動態效果」時,直接以最終值渲染,不播放計數與掃描動畫
svg帶role="img"與aria-label,朗讀時報出目前百分比
常見問題
可以在 Next.js App Router 使用嗎?
可以。原始碼已經有 "use client",在 Server Component 頁面直接 import 即可。伺服器端與首次渲染會先輸出 0,掛載後才播放到目標值。
超過 100 或小於 0 的值會怎樣?
value 會被夾在 0 到 100 之間,NaN 視為 0,所以弧線與數字不會溢出。
漸層的方向可以調整嗎?
陣列形式的 color 會建立一條從左上到右下的 linearGradient,顏色依陣列順序平均分佈,方向本身沒有開放成 prop。需要不同方向時,可以直接修改原始碼裡的 x1、y1、x2、y2。
螢幕閱讀器會怎麼讀?
svg 帶有 role="img" 與 aria-label,內容是目標值加上 suffix,例如「72%」。系統開啟「減少動態效果」時,直接顯示最終值,不播放動畫。
需要哪些依賴?
motion、clsx、tailwind-merge,以及 @/lib/utils 的 cn。不使用 CLI 時,切到「手動」分頁複製原始碼即可。