Container Scroll 3d
捲動時容器 3D 旋轉揭示內容,由後仰逐漸攤平,把畫面推到觀者眼前。
隨頁面捲動把容器從後仰視角攤平面向觀者,適合在 hero 或 feature 段落揭示產品畫面、儀表板或圖表。透過 useScroll 綁定元素在視口中的行程,攤平、縮放與陰影全由捲動進度驅動。
把這個效果裝進你的專案
在專案資料夾執行指令,CLI 會加入原始碼與依賴套件,再依下方使用範例引用元件。
npx webberui@latest add container-scroll-3dContainer Scroll 3d 是用 React、Tailwind CSS 與 Motion 做的捲動 3D 揭示(scroll 3D animation)元件:以 Motion 的 useScroll 追蹤元素的捲動進度,把帶視窗列的卡片從後仰角度轉成正面,用來展示產品截圖或 Dashboard 畫面。
Playground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
<ContainerScroll3d/>
完整範例包含預覽的排版與資料。先安裝元件,再把範例檔貼入你的專案。
適用情境
- SaaS 首頁 hero 下方的產品畫面展示,使用者往下捲時把 Dashboard 截圖攤平到眼前。
- 功能介紹頁的單一主打功能,搭配標題說明再揭示畫面。
- App 或桌面工具的發表頁,在卡片裡放錄影或
video。 - 文件站或部落格文章裡的大型示意圖、圖表展示。
安裝
npx webberui@latest add https://webberui.com/r/container-scroll-3d.json或在 components.json 設定 registries 後,改用 @webberui/container-scroll-3d 安裝。
使用
import { ContainerScroll3d } from "@/components/ui/container-scroll-3d";
<ContainerScroll3d title={<h2 className="text-3xl font-bold">捲動即揭示</h2>}>
<img src="/dashboard.png" alt="Dashboard" className="w-full" />
</ContainerScroll3d>;children 就是攤平後揭示的內容,可放任何 JSX:截圖、video、圖表或即時元件。title 為選填,會隨捲動輕微上移淡入。
範例
用 Next.js Image 放產品截圖
children 會放進卡片內的圓角畫面區,直接放 next/image 即可;title 是卡片上方會淡入的標題。
import Image from "next/image";
import { ContainerScroll3d } from "@/components/ui/container-scroll-3d";
export function ProductShowcase() {
return (
<section className="py-24">
<ContainerScroll3d
title={
<>
<h2 className="text-4xl font-semibold tracking-tight">所有專案,一張表就看完</h2>
<p className="mt-3 text-neutral-500">進度、負責人與截止日集中在同一個畫面。</p>
</>
}
>
<Image src="/screens/dashboard.png" alt="專案總覽畫面" width={1600} height={1000} className="h-auto w-full" />
</ContainerScroll3d>
</section>
);
}角度收斂一點、放錄影
rotate 調小初始仰角,perspective 調大讓透視較平緩,cardClassName 可以改卡片外框樣式。
<ContainerScroll3d
rotate={12}
perspective={1600}
scaleFrom={1}
cardClassName="max-w-5xl"
>
<video src="/videos/editor.mp4" autoPlay loop muted playsInline className="w-full" />
</ContainerScroll3d>在巢狀捲動容器裡使用
如果捲動發生在 overflow-y-auto 的容器內而不是整個視窗,把該容器的 ref 傳給 container。
"use client";
import * as React from "react";
import { ContainerScroll3d } from "@/components/ui/container-scroll-3d";
export function ScrollPanel() {
const scrollRef = React.useRef<HTMLDivElement>(null);
return (
<div ref={scrollRef} className="h-[600px] overflow-y-auto">
<div className="h-[400px]" />
<ContainerScroll3d container={scrollRef}>
<img src="/screens/report.png" alt="月報表畫面" className="w-full" />
</ContainerScroll3d>
<div className="h-[400px]" />
</div>
);
}內嵌畫面自動捲動與景深
內容比畫面高時(長頁面截圖、清單、表格),開 autoScroll 會把畫面區改成 16:10 的視窗,使用者沒操作時以每秒約 24px 慢速上下往返捲動,捲到頂或底停約 1.2 秒再反向;滑鼠移入、鍵盤聚焦或使用者自己滾輪/觸控後都會暫停,閒置 2 秒才接續。dof 在畫面上下邊緣加漸層遮罩與輕微模糊,像鏡頭景深,讓捲動中的內容有前後層次。兩者可分開使用,預設都關閉。
<ContainerScroll3d autoScroll dof>
<img src="/screens/landing-full.png" alt="完整著陸頁截圖" className="w-full" />
</ContainerScroll3d>Props
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
title | React.ReactNode | — | 卡片上方標題,隨捲動上移淡入 |
children | React.ReactNode | — | 卡片內揭示的內容 |
rotate | number | 22 | 初始向後仰角(deg),中段歸零攤平 |
scaleFrom | number | 1.05 | 初始縮放,攤平時收斂到 1 |
titleTranslate | number | 40 | 標題上移距離(px) |
perspective | number | 1000 | 3D 透視深度(px),越小透視越誇張 |
container | React.RefObject | — | 巢狀捲動容器的 ref;預設以視窗為捲動容器 |
className | string | — | 外層容器樣式 |
cardClassName | string | — | 卡片外框樣式 |
autoScroll | boolean | false | 畫面區改為 16:10 視窗並在閒置時自動慢速上下捲動;hover/focus 暫停,減少動態效果時停用 |
dof | boolean | false | 畫面上下邊緣加漸層遮罩與模糊,模擬景深 |
可及性
- 使用
useScroll綁定元素在視口的行程,離開視口即停止計算,不佔用額外資源 - 開啟
autoScroll時畫面區是可聚焦的region(附aria-label),可用 Tab 聚焦後以方向鍵手動捲動;聚焦或滑鼠移入時自動捲動暫停,畫面離開視口或分頁隱藏時也會暫停 dof的模糊層是aria-hidden且不攔截指標事件,不影響點擊與閱讀器- 使用者系統開啟「減少動態效果」時,卡片直接以攤平靜態呈現,不套用捲動變換;
autoScroll也停用,畫面仍可手動捲動
常見問題
可以在 Next.js App Router 使用嗎?
可以。原始碼已有 "use client",在 Server Component 頁面直接 import,children 也可以放 Server Component 產生的內容。首次渲染與伺服器端一致,掛載後才依減少動態效果設定切換成靜態版。
為什麼卡片一直沒有攤平?
動畫進度從元件頂端進入視窗底部開始,到元件底端離開視窗頂部結束,卡片在進度 0.1 到 0.55 之間攤平。如果頁面在元件之後沒有足夠的捲動距離,進度就到不了,可以在下方保留更多內容或空間。若捲動發生在巢狀容器內,記得傳入 container。
怎麼調整 3D 效果的強度?
rotate 是初始仰角(預設 22 度),perspective 是透視深度(預設 1000px,越小越誇張),scaleFrom 是初始縮放(預設 1.05),titleTranslate 是標題上移的距離。
可以拿掉卡片上方的三顆圓點嗎?
視窗列寫在原始碼的 ScrollCard 裡,沒有對應的 prop;複製原始碼後直接刪除那段 JSX 即可。
使用者開啟減少動態效果時會怎樣?
卡片直接以攤平的靜態樣子顯示,標題也不做位移與淡入。