Zoom Lens
圖片放大鏡,鏡片跟隨游標就地放大,或以側邊面板呈現放大結果。
把這個效果裝進你的專案
在專案資料夾執行指令,CLI 會加入原始碼與依賴套件,再依下方使用範例引用元件。
npx webberui@latest add zoom-lensZoom Lens 是用 React、Tailwind CSS 與 Motion 做的圖片放大鏡(image zoom/商品圖放大)元件:滑鼠移到圖上,圓形或方形鏡片會跟著游標就地放大局部細節;也可以切到 panel 模式,在原圖旁另開一塊面板顯示放大結果。
Playground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
<ZoomLens/>
完整範例包含預覽的排版與資料。先安裝元件,再把範例檔貼入你的專案。
適用情境
- 電商商品頁的主圖,讓買家看清布料紋理、縫線或金屬表面。
- 作品集或攝影網站,展示高解析度原圖的局部細節。
- 產品規格頁的電路板、零件特寫,需要放大才看得清標示。
- 地圖、平面圖、設計稿等資訊密度高的圖片預覽。
安裝
npx webberui@latest add https://webberui.com/r/zoom-lens.json或在 components.json 設定 registries 後,改用 @webberui/zoom-lens 安裝。
使用
import { ZoomLens } from "@/components/ui/zoom-lens";
<ZoomLens
src="/product.jpg"
alt="產品細節圖"
className="w-full max-w-md"
/>側邊面板模式
panel variant 會在原圖上標示取景框,並於側邊面板顯示放大結果,適合電商商品圖。
<ZoomLens
src="/product.jpg"
alt="產品細節圖"
variant="panel"
panelPosition="right"
zoom={2.6}
size={200}
className="w-64"
/>範例
方形鏡片與較高倍率
shape="square" 搭配較大的 zoom,適合需要看清細小文字或紋路的圖片。
<ZoomLens
src="/pcb-board.jpg"
alt="主機板元件特寫"
shape="square"
zoom={4}
size={180}
className="w-full max-w-lg"
/>商品圖庫:切換縮圖
src 換掉時鏡片與放大背景會跟著使用新圖,可以直接接在縮圖列後面。
"use client";
import { useState } from "react";
import { ZoomLens } from "@/components/ui/zoom-lens";
const photos = ["/shoe-side.jpg", "/shoe-top.jpg", "/shoe-sole.jpg"];
export function ProductGallery() {
const [current, setCurrent] = useState(photos[0]);
return (
<div className="space-y-3">
<ZoomLens
src={current}
alt="跑鞋商品圖"
variant="panel"
panelPosition="right"
className="w-72"
/>
<div className="flex gap-2">
{photos.map((p) => (
<button key={p} type="button" onClick={() => setCurrent(p)}>
<img src={p} alt="" className="size-14 rounded-md object-cover" />
</button>
))}
</div>
</div>
);
}放大時隱藏說明文字
onZoomChange 會在放大開啟與關閉時各觸發一次,可用來同步其他 UI,例如放大期間淡出圖說。
const [zooming, setZooming] = useState(false);
<figure>
<ZoomLens
src="/watch-dial.jpg"
alt="錶盤細節"
onZoomChange={setZooming}
className="w-full max-w-md"
/>
<figcaption className={zooming ? "opacity-0" : "opacity-100"}>
移動滑鼠查看錶盤刻度
</figcaption>
</figure>Props
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
src | string | — | 圖片來源網址 |
alt | string | "" | 圖片替代文字 |
variant | "lens" | "panel" | "lens" | 放大呈現方式 |
zoom | number | 2.5 | 放大倍率 |
size | number | 160 | 鏡片直徑(lens)/面板邊長(panel),單位 px |
shape | "circle" | "square" | "circle" | 鏡片形狀(僅 lens) |
panelPosition | "right" | "left" | "top" | "bottom" | "right" | 面板位置(僅 panel) |
disabled | boolean | false | 停用放大互動,僅顯示原圖 |
onZoomChange | (active: boolean) => void | — | 放大開關狀態變更回呼 |
className | string | — | 圖片框 className,於此指定圖片尺寸 |
imageClassName | string | — | <img> 的 className |
細節
- 於
className給定寬度(如w-full max-w-md),圖片以h-auto依原比例撐開,元件透過ResizeObserver量測顯示尺寸並據此計算放大背景。 - 取景中心會被夾取在圖片範圍內,放大內容不會露出空白邊。
- 位置以 Motion spring 平滑跟隨;
lens與panel共用同一套背景座標運算,倍率與尺寸表現一致。 - 支援滑鼠、觸控與觸控筆(Pointer Events);觸控時以拖曳移動取景,放開即收起。
可及性
<img>保留alt,放大互動屬漸進增強,輔助科技仍可正常朗讀圖片。- 鏡片、取景框、放大面板皆為裝飾層並標記
aria-hidden,不干擾閱讀順序。 - 使用者系統開啟「減少動態效果」時,跟隨與淡入淡出動畫即時到位、不使用 spring 與縮放。
- 元件會清理
ResizeObserver,卸載時不遺留監聽。
常見問題
可以在 Next.js App Router 使用嗎?
可以。原始碼第一行已有 "use client",它是 Client Component,在 Server Component 頁面中照一般方式 import 即可。
怎麼調整放大倍率與鏡片大小?
用 zoom 設定倍率(預設 2.5),size 設定鏡片直徑或面板邊長(預設 160 px)。圖片本身的寬度則寫在 className,例如 w-full max-w-md。
手機上能用嗎?
可以。元件使用 Pointer Events,觸控時以拖曳移動取景,手指放開就收起;滑鼠則會維持到游標離開圖片為止。不想在某些情況下啟用放大,可傳入 disabled。
需要另外準備高解析度大圖嗎?
元件用同一個 src 當作放大背景,以顯示尺寸乘上 zoom 計算背景大小。原圖解析度越高,放大後越清楚;解析度不足時放大內容會模糊。
需要哪些依賴?
motion、lucide-react、clsx 與 tailwind-merge。不想用 CLI 的話,切到安裝區的「手動」分頁複製原始碼即可。