背景
漂浮卡片場
一群卡片在 3D 空間的不同深度緩慢漂浮:游標視差依深度不同,捲動時整體拉遠並散開,遠景帶景深模糊。
把作品縮圖、介面截圖或任意節點散佈在不同深度,做成首頁或作品集的背景。每張卡片的位置、深度、旋轉與尺寸由種子與索引確定性產生,SSR 與瀏覽器結果一致;近景大而清晰、遠景小而模糊。游標移動時近景位移多、遠景位移少,形成視差;往下捲離開時整片卡片拉遠並由中心向外散開。中央可放標題與按鈕,前景內容不參與漂移。
把這個效果裝進你的專案
在專案資料夾執行指令,CLI 會加入原始碼與依賴套件,再依下方使用範例引用元件。
npx webberui@latest add "https://webberui.com/r/floating-card-field.json?t=<安裝 token>"Playground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
12
4
10
40
9
編輯中的呼叫預設屬性
<FloatingCardField/>
完整範例包含預覽的排版與資料。先安裝元件,再把範例檔貼入你的專案。
安裝
npx webberui@latest add "https://webberui.com/r/floating-card-field.json?t=<安裝 token>"或在 components.json 設定 registries 後,改用 @webberui/floating-card-field 安裝。
使用
import {
FloatingCardField,
type FloatingCard,
} from "@/components/ui/floating-card-field";
const cards: FloatingCard[] = [
{ id: "a", src: "/works/dashboard.png" },
{ id: "b", src: "/works/album.png" },
{ id: "c", node: <div className="h-full w-full bg-gradient-to-br from-sky-400 to-indigo-500" /> },
// 指定位置與深度會覆蓋自動佈局
{ id: "d", src: "/works/player.png", x: 30, y: -20, z: 0.1 },
];
<FloatingCardField cards={cards} height="100vh" depthBlur={4} parallax={40}>
<h1 className="text-4xl font-semibold">你的作品,值得被看見</h1>
</FloatingCardField>;Props
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
cards | FloatingCard[] | — | 卡片清單 |
count | number | — | 只使用前 count 張;未提供時全部使用 |
seed | number | 1 | 佈局種子,換一個數字就換一組排列 |
depthBlur | number | 4 | 景深模糊(px),卡片模糊量 = 深度 × depthBlur |
parallax | number | 40 | 游標視差最大位移(px),乘上(1 − 深度) |
drift | number | 10 | 每張卡片緩慢漂移的幅度(px) |
scatter | number | 160 | 捲動離開時由中心向外散開的最大距離(px) |
cardWidth | number | 168 | 卡片基準寬度(px),再乘上 0.8–1.2 的尺寸係數,高寬比 3:4 |
height | number | string | "100vh" | 容器高度;數字為 px |
container | RefObject<HTMLElement | null> | — | 捲動發生在巢狀 overflow 容器時傳入;預設以視窗為捲動容器 |
children | ReactNode | — | 中央前景內容,不參與漂移 |
className | string | — | 透傳到最外層容器 |
FloatingCard
| 欄位 | 型別 | 預設值 | 說明 |
|---|---|---|---|
id | string | — | React key;未提供時以索引代替 |
node | ReactNode | — | 卡片內容,優先於 src |
src | string | — | 你自己的圖片網址 |
alt | string | "" | 圖片替代文字;卡片場為裝飾,通常留空 |
x | number | hash | 相對中心的水平百分比(−45~45) |
y | number | hash | 相對中心的垂直百分比(−40~40) |
z | number | hash | 深度 0–1,0 最近、1 最遠 |
另外具名匯出 FloatingCard 與 FloatingCardFieldProps 型別。
細節
- 確定性佈局:每張卡以
mulberry32由 seed 與索引產生位置、深度、旋轉(−8°~8°)、尺寸(0.8–1.2)與漂移節奏,不用Math.random,伺服器與瀏覽器渲染結果相同 - 深度呈現:縮放 = 1 − 深度 × 0.5、不透明度 = 1 − 深度 × 0.35、模糊 = 深度 × depthBlur,近的卡片疊在上層。深度用縮放模擬而非
translateZ,因為filter模糊會讓preserve-3d被壓平 - 游標視差:游標相對容器中心換算成 −1~1,經彈簧(stiffness 80、damping 20)平滑後乘上(1 − 深度)× parallax;觸控裝置不啟用
- 漂移節奏:每張卡套用 CSS keyframes 緩慢浮動,週期為
--wb-fcf-drift-period(預設9s)乘上 0.67–1.33 的係數,並以負的 animation-delay 錯開。覆寫這個變數即可整體加快或放慢 - 捲動拉遠:捲動進度從容器頂端貼齊視窗頂端(0)到容器底端離開視窗頂端(1),整片縮到 0.7 倍,每張卡沿中心向外的方向位移 scatter px,不透明度再降 30%
- 暫停:容器離開視窗時,漂移動畫暫停、視差停止更新
可及性
- 卡片場是裝飾,整層為
aria-hidden且不接收指標事件;不建議在卡片內放可聚焦元素 children放在獨立的前景層,不會被隱藏,標題與按鈕可正常讀取與操作- 使用者系統開啟「減少動態效果」時,沒有漂移、沒有游標視差、也沒有捲動拉遠散開,卡片靜止在初始位置;景深模糊與縮放屬於靜態深度提示,仍保留