Hero Parallax Grid
多列反向視差的產品/作品牆,捲動時每一排以不同方向掃過並帶 3D 進場。
以捲動進度驅動的英雄視差牆:項目切成多列,相鄰列橫向反向位移,並在進場前 20% 完成 rotateX 與淡入,形成景深穿越感。
把這個效果裝進你的專案
在專案資料夾執行指令,CLI 會加入原始碼與依賴套件,再依下方使用範例引用元件。
npx webberui@latest add "https://webberui.com/r/hero-parallax-grid.json?t=<安裝 token>"Hero Parallax Grid 是用 React、Tailwind CSS 與 Motion(useScroll、useTransform)做的捲動視差(scroll parallax)作品牆:圖片平均切成多列,捲動時相鄰兩列朝相反方向橫移,整組在捲動前段從傾斜的 3D 角度轉正並淡入。
Playground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
<HeroParallaxGrid/>
完整範例包含預覽的排版與資料。先安裝元件,再把範例檔貼入你的專案。
適用情境
- 設計工作室、接案者的首頁英雄區,一次展示大量作品縮圖。
- SaaS 或 App 官網展示範本庫、主題或模板截圖。
- 電商品牌頁的新品系列、商品陳列牆。
- 活動或作品展的回顧頁,捲動時快速掃過大量照片。
- 不適合:只需要一排圖片或 logo 持續循環跑動時,改用 Velocity Marquee。
安裝
npx webberui@latest add "https://webberui.com/r/hero-parallax-grid.json?t=<安裝 token>"或在 components.json 設定 registries 後,改用 @webberui/hero-parallax-grid 安裝。
使用
import { HeroParallaxGrid } from "@/components/ui/hero-parallax-grid";
const items = [
{ src: "/work/nova.jpg", alt: "Nova", title: "Nova" },
{ src: "/work/ember.jpg", alt: "Ember", title: "Ember" },
// 建議 9–15 張
];
<HeroParallaxGrid
items={items}
title="精選作品牆"
description="多列反向視差。"
/>;外層軌道容器的高度(className 的 h-*)決定可捲動距離;容器越高,視差掃過越慢越完整。若捲動發生在巢狀 overflow 區塊內,將該容器的 ref 傳給 container。
範例
只傳圖片網址
items 也接受純字串陣列;沒有 alt 的圖片會標記為 aria-hidden,視為裝飾。cardWidth 與 cardHeight 調整每張卡片的尺寸。
import { HeroParallaxGrid } from "@/components/ui/hero-parallax-grid";
const shots = Array.from({ length: 12 }, (_, i) => `/templates/template-${i + 1}.jpg`);
<HeroParallaxGrid
items={shots}
title="可直接套用的頁面範本"
description="登入頁、定價頁、部落格與後台介面,複製後即可修改。"
cardWidth={240}
cardHeight={160}
/>調整列數、速度與圖片樣式
rows 決定切成幾列,travel 是捲動全程每列橫移的距離(px);外層高度用 className 設定,越高捲動距離越長。imageClassName 套用在每張圖片上,卡片本身帶有 group,可以搭配 group-hover: 使用。
<HeroParallaxGrid
items={works}
rows={2}
travel={480}
className="h-[2000px]"
imageClassName="grayscale transition duration-300 group-hover:grayscale-0"
aria-label="近期作品"
/>放在可捲動的容器內
捲動發生在巢狀 overflow 區塊(例如預覽面板)時,把該容器的 ref 傳給 container,捲動進度才會以它為準。
"use client";
import * as React from "react";
import { HeroParallaxGrid } from "@/components/ui/hero-parallax-grid";
export function PreviewPane({ items }: { items: string[] }) {
const scrollerRef = React.useRef<HTMLDivElement>(null);
return (
<div ref={scrollerRef} className="h-[600px] overflow-y-auto rounded-xl border">
<HeroParallaxGrid items={items} container={scrollerRef} className="h-[1400px]" />
</div>
);
}Props
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
items | (string | { src; alt?; title? })[] | — | 產品/作品項目,建議 9–15 張 |
container | RefObject<HTMLElement> | undefined | 巢狀捲動容器;預設以視窗為捲動來源 |
rows | number | 3 | 切成幾列,相鄰列反向位移 |
travel | number | 320 | 每列橫向位移距離(px),越大掃過越快 |
title | string | undefined | 頂部標題(省略則不渲染) |
description | string | undefined | 標題下方描述 |
cardWidth | number | 200 | 卡片寬度(px) |
cardHeight | number | 150 | 卡片高度(px) |
aria-label | string | "視差產品牆" | 圖組無障礙名稱 |
className | string | undefined | 軌道容器;高度決定可捲動距離 |
imageClassName | string | undefined | 套用到每張卡片圖片 |
可及性
- 使用者系統開啟「減少動態效果」時,改渲染靜態網格,不做捲動視差
- 整組帶
role="group"與aria-label;無alt的圖片標記為aria-hidden
常見問題
可以在 Next.js App Router 使用嗎?
可以。元件檔案開頭已有 "use client",在 Server Component 頁面直接 import 並傳入 items 即可。首次渲染固定輸出視差版本,掛載後才依「減少動態效果」設定切換,伺服器與用戶端的初始輸出一致。
圖片會用 next/image 最佳化嗎?
不會。卡片內使用一般的 <img>(object-cover、不可拖曳)。需要圖片最佳化時,可以先用你的 CDN 或圖片服務產生適當尺寸的網址再傳入,或修改原始碼中的 ProductCard。
視差掃得太快或太慢怎麼調?
兩個因素:travel(每列橫移距離,預設 320 px)與外層高度(預設 h-[1600px],用 className 覆寫)。同樣的 travel 配上較高的容器,捲動起來會比較慢。
放幾張圖比較適合?
原始碼建議 9 到 15 張。項目會平均分到 rows 列中,每列張數是總數除以列數後無條件進位。
開啟減少動態效果時會怎樣?
系統開啟「減少動態效果」時,元件改渲染靜態的響應式網格(2 到 4 欄),保留標題與描述,不做捲動視差與 hover 上浮。依賴只有 motion、clsx 與 tailwind-merge。