輪播
放射畫廊
圖片從中心爆開排成一圈後緩慢公轉,點選任一張飛到中央放大、其餘縮回環上,支援鍵盤切換。
把一組圖片排成會呼吸的圓環。進入視窗時每張卡片從中心以彈簧錯開爆開到環上,接著整圈緩慢公轉,滑鼠移上或鍵盤聚焦時平順減速停下。點選任一張,它會以共享版面動畫飛到中央放大、下方淡入說明,其餘卡片縮小變淡留在環上;再點中央、按 Esc 或點空白處就飛回原位。每張卡片可以是圖片網址,也可以是任意 React 節點(例如 CSS 漸層畫的圖)。選取狀態支援受控/非受控雙模式。
把這個效果裝進你的專案
在專案資料夾執行指令,CLI 會加入原始碼與依賴套件,再依下方使用範例引用元件。
npx webberui@latest add radial-burst-galleryPlayground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
180
40
180
96
編輯中的呼叫預設屬性
<RadialBurstGallery/>
完整範例包含預覽的排版與資料。先安裝元件,再把範例檔貼入你的專案。
安裝
npx webberui@latest add https://webberui.com/r/radial-burst-gallery.json或在 components.json 設定 registries 後,改用 @webberui/radial-burst-gallery 安裝。
使用
import { RadialBurstGallery } from "@/components/ui/radial-burst-gallery";
<RadialBurstGallery
images={[
{ src: "/photos/ridge.jpg", alt: "霧中的稜線", caption: "霧中的稜線|合歡山" },
{ src: "/photos/tide.jpg", alt: "退潮之後", caption: "退潮之後|高美濕地" },
{ src: "/photos/blue.jpg", alt: "藍色時刻", caption: "藍色時刻|北海岸" },
]}
radius={180}
period={40}
onSelectedChange={(index) => console.log("選取", index)}
/>Props
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
images | RadialBurstGalleryImage[] | — | 圖片清單,依陣列順序從正上方順時針排成一圈 |
radius | number | 180 | 環的半徑(px);容器太窄時自動縮成 min(radius, 容器寬/2 − 卡寬) |
period | number | 40 | 環公轉一圈的秒數;未提供時讀取 CSS 變數 --wb-rbg-period,再退回 40 秒 |
stiffness | number | 180 | 爆開與飛行彈簧的剛性,數字越大越俐落 |
cardWidth | number | 96 | 環上卡片寬度(px) |
aspect | string | "3/4" | 卡片寬高比,格式為「寬/高」 |
centerSize | number | 260 | 選取後中央卡片的寬度(px);容器太窄時自動縮小 |
tiltToCenter | boolean | false | 讓環上卡片的頂端朝外(隨角度旋轉),預設保持正立 |
selectedIndex | number | null | — | 受控的選取索引(null 表示未選取);未提供時由元件內部管理 |
defaultSelectedIndex | number | null | null | 非受控模式的初始選取索引 |
onSelectedChange | (index: number | null) => void | — | 選取變動時回呼,取消選取時參數為 null |
pauseOnHover | boolean | true | 滑鼠移到卡片上時暫停公轉 |
className | string | — | 透傳到最外層容器 |
RadialBurstGalleryImage
| 欄位 | 型別 | 預設值 | 說明 |
|---|---|---|---|
src | string | — | 圖片網址;與 node 擇一,兩者都給時以 node 為準 |
alt | string | — | 替代文字,同時作為卡片按鈕的 aria-label(必填) |
node | ReactNode | — | 自訂內容,例如 CSS 漸層畫出的圖 |
caption | ReactNode | — | 選取後顯示在中央卡片下方的說明 |
細節
- 幾何:n 張卡片平均分布在圓上,第 i 張的角度是 i/n × 360° 加上環的旋轉角,從正上方順時針排列;卡片只平移不旋轉,開啟
tiltToCenter才讓頂端朝外。 - 爆開:第一次進入視窗時,每張卡片從中心以 scale 0.3、透明度 0 出發,以彈簧(
stiffness預設 180、damping 18)飛到環上,每張錯開 50ms;彈簧會略微衝出環外再回彈。之後捲走再回來不會重播。 - 公轉:以 requestAnimationFrame 依
period推進旋轉角;滑鼠移到卡片上、鍵盤焦點在畫廊內或有卡片被選取時,速度在 150ms 內漸變到 0,不會瞬停。畫廊離開視窗時停止動畫迴圈。 - 節奏變數:不傳
period時,元件讀取根元素上的--wb-rbg-period(可寫40s或40000ms),方便以全域樣式統一調整;明確傳入的period優先。 - 選取:被選中的卡片以 Motion 的
layoutId(以useId為前綴,同頁多個畫廊不互相干擾)飛到中央放大到centerSize;其餘卡片縮到 0.8、透明度 0.6。環上卡片以 left/top 定位而非 transform,讓共享版面動畫量到正確的起點。 - 窄容器:以 ResizeObserver 量測容器寬,半徑自動縮成 min(radius, 容器寬/2 − 卡寬),中央卡片寬度不超過容器寬減 32px。
可及性
- 外層為
role="group"、aria-roledescription="畫廊";每張卡片是type="button",aria-label取自alt - 採 roving tabindex:Tab 只停在一張卡片上,←/→(與 ↑/↓)依環順序移動焦點,Home/End 跳到第一張與最後一張;焦點在畫廊內時環暫停公轉
- Enter/Space 選取,焦點移到中央卡片;Esc、再按一次中央卡片或點空白處取消選取,焦點回到原本那張卡片
- 選取時
aria-live="polite"區域宣告「第幾張,共幾張」與 caption(沒有 caption 時讀 alt) - 使用者系統開啟「減少動態效果」時,不爆開也不公轉,卡片直接靜態排成一圈;選取改為中央交叉淡入,沒有飛行動畫