媒體
封面牆
由中心向外逐格填入的封面格子牆 React 元件,中央疊放逐位滾動的計數與文案,滑過單格推近、鄰格微退,可點擊選取。
把一整面書封、專輯或作品縮圖排成網格,進入視口時逐格浮現——每格由模糊、略小、透明淡入到定位。填入順序可選由中心向外、逐列或確定性打亂;網格中央疊放一層放射狀遮罩,上面是逐位滾動的計數數字、標題與說明。滑鼠滑過單格時該格推近、陰影加深,周圍八格微微退後;傳入 onSelect 後每格都是可點擊的按鈕。
把這個效果裝進你的專案
在專案資料夾執行指令,CLI 會加入原始碼與依賴套件,再依下方使用範例引用元件。
npx webberui@latest add cover-wallPlayground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
28
500
6
編輯中的呼叫預設屬性
<CoverWall/>
完整範例包含預覽的排版與資料。先安裝元件,再把範例檔貼入你的專案。
安裝
npx webberui@latest add https://webberui.com/r/cover-wall.json或在 components.json 設定 registries 後,改用 @webberui/cover-wall 安裝。
使用
import { CoverWall } from "@/components/ui/cover-wall";
<CoverWall
images={covers} // { src: string; alt: string }[]
columns={6}
order="center-out"
counter={500}
counterSuffix="+"
title="本月新書牆"
description="本好書陸續上架"
onSelect={(index) => console.log(covers[index].alt)}
/>沒有圖片時也可以直接放任意格子內容:
<CoverWall columns={5} aspect="1/1">
{albums.map((album) => (
<AlbumTile key={album.id} album={album} />
))}
</CoverWall>Props
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
images | CoverWallImage[] | — | 封面圖片陣列;未提供時改用 children,每個子元素是一格 |
children | React.ReactNode | — | 任意格子內容(每個子元素一格);有 images 時忽略 |
columns | number | 6 | 欄數;螢幕寬度小於 640px 時最多 4 欄 |
aspect | string | "3/4" | 每格的長寬比(CSS aspect-ratio),圖片載入前先預留空間 |
gap | number | 6 | 格子間距(px) |
order | "center-out" | "row" | "random" | "center-out" | 填入順序:由中心向外、逐列、確定性打亂 |
stagger | number | 28 | 每格之間的延遲(ms);未提供時讀 --wb-cw-stagger |
counter | number | null | null | 中央疊放的計數數字;null 時不顯示 |
counterSuffix | string | "+" | 計數數字後綴 |
title | React.ReactNode | — | 中央標題 |
description | React.ReactNode | — | 中央說明文字 |
onSelect | (index: number) => void | — | 點擊格子(或聚焦後按 Enter/空白鍵)時回呼,參數為格子索引;提供時每格變成按鈕 |
className | string | — | 透傳到最外層容器 |
CoverWallImage
| 欄位 | 型別 | 預設值 | 說明 |
|---|---|---|---|
src | string | — | 圖片網址(使用者自己的圖;元件不內建任何外部圖片) |
alt | string | — | 替代文字;可點擊時同時作為按鈕的 aria-label |
細節
- 填入:網格進入視口(IntersectionObserver,只觸發一次)後,每格依排名延遲
排名 × stagger,以 420ms 從opacity 0、scale(0.9)、blur(6px)過渡到定位。 - 順序:
center-out依格子到網格中心的歐氏距離排序;row由左上逐列;random以 index 的確定性雜湊打亂,SSR 與瀏覽器結果一致。窄螢幕切成 4 欄時順序與鄰格會依實際欄數重算。 - 計數:每一位是 0–9 的直列滾輪,以 spring(stiffness 120、damping 20)滾到目標位,在填入進度約 60% 時開始。
- 圖片以
loading="lazy"、decoding="async"、object-cover載入,外層aspect-ratio先預留空間,不會跳版。 - 可覆寫的 CSS 變數:
--wb-cw-stagger(28ms)、--wb-cw-fill-duration(420ms)、--wb-cw-hover-duration(200ms)、--wb-cw-ease(cubic-bezier(0.23,1,0.32,1))、--wb-cw-scrim(中央遮罩色,預設 neutral-950 的 70%)。 - hover 推近只在精準指標(滑鼠、觸控板)生效,觸控裝置點擊不會縮放。
可及性
- 格子是
ul/li清單;傳入onSelect時每格是type="button",可用 Tab 聚焦、Enter/空白鍵選取,並有 focus-visible 外框 - 使用
images且可點擊時,按鈕以圖片alt作為aria-label;不可點擊時圖片保留原本的alt - 中央疊層不攔截指標;計數區
aria-live="off",螢幕閱讀器只讀完整數值,滾動中的位數以aria-hidden隱藏 - 使用者系統開啟「減少動態效果」時,所有格子直接出現、計數直接顯示最終值,hover 只加深陰影、不縮放也不讓鄰格退後