滾動效果

Container Scroll 3d

捲動時容器 3D 旋轉揭示內容,由後仰逐漸攤平,把畫面推到觀者眼前。

隨頁面捲動把容器從後仰視角攤平面向觀者,適合在 hero 或 feature 段落揭示產品畫面、儀表板或圖表。透過 useScroll 綁定元素在視口中的行程,攤平、縮放與陰影全由捲動進度驅動。

把這個效果裝進你的專案

在專案資料夾執行指令,CLI 會加入原始碼與依賴套件,再依下方使用範例引用元件。

npx webberui@latest add container-scroll-3d

還沒有專案,或安裝遇到問題?看快速開始 →

Container Scroll 3d 是用 React、Tailwind CSS 與 Motion 做的捲動 3D 揭示(scroll 3D animation)元件:以 Motion 的 useScroll 追蹤元素的捲動進度,把帶視窗列的卡片從後仰角度轉成正面,用來展示產品截圖或 Dashboard 畫面。

Playground

即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。

22
1.05
40
1000
編輯中的呼叫預設屬性
<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型別預設值說明
titleReact.ReactNode—卡片上方標題,隨捲動上移淡入
childrenReact.ReactNode—卡片內揭示的內容
rotatenumber22初始向後仰角(deg),中段歸零攤平
scaleFromnumber1.05初始縮放,攤平時收斂到 1
titleTranslatenumber40標題上移距離(px)
perspectivenumber10003D 透視深度(px),越小透視越誇張
containerReact.RefObject—巢狀捲動容器的 ref;預設以視窗為捲動容器
classNamestring—外層容器樣式
cardClassNamestring—卡片外框樣式
autoScrollbooleanfalse畫面區改為 16:10 視窗並在閒置時自動慢速上下捲動;hover/focus 暫停,減少動態效果時停用
dofbooleanfalse畫面上下邊緣加漸層遮罩與模糊,模擬景深

可及性

  • 使用 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 即可。

使用者開啟減少動態效果時會怎樣?

卡片直接以攤平的靜態樣子顯示,標題也不做位移與淡入。