Exploded View Scroll
捲動分解圖:區塊釘住後商品的分層去背圖像沿 Z 軸炸開,各層由引線標註的規格依序浮現,捲畢再收攏回完整商品釋放至下一區塊。
載入預覽⋯
Playground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
88
120
900
3
<ExplodedViewScroll />
安裝
npx shadcn@latest add https://webberui.com/r/exploded-view-scroll.json或在 components.json 設定 registries 後,改用 @webberui/exploded-view-scroll 安裝。
安裝依賴後,從 registry JSON(/r/exploded-view-scroll.json 的 files[0].content)複製 exploded-view-scroll.tsx 原始碼到你的 components/ui/ 目錄:
npm install motion clsx tailwind-merge使用
傳入由前到後排列的 layers(陣列首為最上/最遠層,末為最下/最近層)。捲動軌道容器內的舞台會被釘住,層片沿 Z 軸炸開後,各層附掛的規格文案會依序浮現;捲到底時層片收攏回完整商品,並隨軌道結束釋放給下一個區塊。
import { ExplodedViewScroll } from "@/components/ui/exploded-view-scroll";
<ExplodedViewScroll
aria-label="耳機分解圖"
stageClassName="h-screen"
layers={[
{
src: "/parts/glass.png",
alt: "玻璃面板",
title: "康寧強化玻璃",
description: "0.4mm 抗刮鍍膜",
side: "right",
},
{
src: "/parts/board.png",
alt: "主機板",
title: "N-series 主機板",
description: "6 核心・16GB",
side: "left",
},
{
src: "/parts/battery.png",
alt: "電池",
title: "矽碳負極電池",
description: "4820mAh・快充",
side: "right",
},
]}
>
<h2 className="text-2xl font-semibold">Aero One</h2>
</ExplodedViewScroll>;若捲動發生在巢狀 overflow-y-auto 容器內,把該容器 ref 傳入 container,並將 stageClassName 設為容器的可視高度(例如 h-[300px])、offsetTop 設為 0。
Props
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
layers | ExplodedLayer[] | — | 由前到後排列的分層(見下表) |
scrollScale | number | 3 | 捲動軌道高度為釘住舞台高度的倍數,越大炸開越從容 |
offsetTop | number | 0 | 釘住舞台的吸頂位置(px) |
spread | number | 88 | 相鄰兩層炸開時的垂直間距(px) |
depth | number | 120 | 相鄰兩層炸開時的 Z 軸景深(px) |
perspective | number | 900 | 透視距離(px),越小 3D 透視越誇張 |
smooth | boolean | true | 是否以 spring 平滑捲動進度 |
container | RefObject<HTMLElement | null> | — | 巢狀捲動容器的 ref;預設以視窗為捲動容器 |
aria-label | string | "商品分解圖" | 舞台的無障礙名稱 |
children | ReactNode | — | 疊在舞台中央、不攔截指標的內容;炸開時淡出 |
className | string | — | 套用在最外層捲動軌道容器 |
stageClassName | string | "h-screen" | 釘住的舞台容器;巢狀捲動時覆寫為容器可視高度 |
layerClassName | string | — | 套用在每層視覺的定位包裹層(可控制尺寸) |
ExplodedLayer
| 欄位 | 型別 | 預設值 | 說明 |
|---|---|---|---|
src | string | — | 此層的去背圖像來源;與 content 二擇一 |
content | ReactNode | — | 此層的自訂內容;優先於 src |
alt | string | "" | 影像/內容的無障礙描述 |
title | string | — | 引線標註的規格標題 |
description | string | — | 引線標註的規格說明 |
side | "left" | "right" | 依索引交錯 | 標註出現在舞台的左側或右側 |
細節
- 炸開遵循「散開 → 維持 → 收攏」三段時序:進場時層片沿 Z 軸分離、中段維持展開讓規格文案依序浮現,捲到底時收攏回完整商品,再隨軌道結束自然釋放至下一區塊。
- 3D 以 CSS
perspective+translateZ實現(非 WebGL):近層在透視下放大、遠層縮小,形成真實景深。 - 引線標註以透視投影後的垂直位置對位層片中心,文字維持水平且銳利,不隨層片一起被縮放。
- 軌道高度會量測釘住舞台的實際高度後乘上
scrollScale自動計算,因此無論是整頁h-screen或巢狀h-[300px]容器都能運作。 smooth開啟時捲動進度會經過 spring 平滑,炸開帶慣性感;關閉則逐格緊貼捲動。
可及性
- 使用者系統開啟「減少動態效果」時,改以靜態圖說列表呈現:每層視覺並排其規格標題與說明,不做任何捲動炸開。
- 動畫視覺與引線標註皆標記
aria-hidden,另提供一份與動畫解耦的sr-only規格清單供輔助科技朗讀完整內容。 - 舞台帶
role="group"與aria-label;中央疊加內容不攔截指標事件(pointer-events-none)。