媒體

Zoom Lens

圖片放大鏡,鏡片跟隨游標就地放大,或以側邊面板呈現放大結果。

把這個效果裝進你的專案

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

npx webberui@latest add zoom-lens

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

Zoom Lens 是用 React、Tailwind CSS 與 Motion 做的圖片放大鏡(image zoom/商品圖放大)元件:滑鼠移到圖上,圓形或方形鏡片會跟著游標就地放大局部細節;也可以切到 panel 模式,在原圖旁另開一塊面板顯示放大結果。

Playground

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

2.5
160
編輯中的呼叫預設屬性
<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型別預設值說明
srcstring—圖片來源網址
altstring""圖片替代文字
variant"lens" | "panel""lens"放大呈現方式
zoomnumber2.5放大倍率
sizenumber160鏡片直徑(lens)/面板邊長(panel),單位 px
shape"circle" | "square""circle"鏡片形狀(僅 lens)
panelPosition"right" | "left" | "top" | "bottom""right"面板位置(僅 panel)
disabledbooleanfalse停用放大互動,僅顯示原圖
onZoomChange(active: boolean) => void—放大開關狀態變更回呼
classNamestring—圖片框 className,於此指定圖片尺寸
imageClassNamestring—<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 的話,切到安裝區的「手動」分頁複製原始碼即可。