A React image zoom component - a magnifier that follows the pointer over any element. For product galleries.
Lens playground
Install Lens
1. New project? One command installs the package and wires everything - see Installation:
pnpm dlx zyncat-ui init2. Import the component - it loads its own stylesheet:
import { Lens } from '@zyncat/ui/lens';Usage
import { Lens } from '@zyncat/ui/lens'; <Lens magnification={2.6} radius={132}> <TypeSpecimen /></Lens>Compose Lens in your application. No Tailwind or external styling library is required; every value resolves from Zyncat UI's token vocabulary.
Lens props
Lens
LensStyle
Frequently asked questions
Wrap it: <Lens magnification={2.6} radius={132}><img src="/product.jpg" /></Lens>. The glass follows the pointer with no lag and magnifies whatever sits under it, so there are no mouse events to wire up. magnification is clamped to 1.2-6 and radius, the glass radius in pixels, to 60-260.
These results are still owned by the jQuery era - elevateZoom, Magic Zoom Plus, YITH WooCommerce Zoom Magnifier - with react-image-magnify, react-medium-image-zoom and js-image-zoom on the React side. Lens differs in what it magnifies: rather than pairing a thumbnail with a separate high-resolution file, it re-renders the DOM you already have, which is why it works over text, SVG and charts as well as photos.
Any DOM. Lens clones its children into the glass and scales that clone about the pointer, so a div, a table, live text, an SVG chart or a map magnifies exactly the way an image does. Because the copy is real DOM and not a bitmap, magnified type is re-rasterised as vector type at the larger size, and a MutationObserver re-clones so content that changes stays live under the glass.
Text, SVG and CSS re-rasterise at the magnified size, so they stay sharp at any magnification. A photo is bounded by the file you hand it, as with any image zoom: serve a high-resolution source and constrain it with CSS width, and the browser has the full-resolution pixels to draw from when the glass magnifies. There is no second image URL prop - Lens magnifies the one child you pass.
A real effect, not a magnifying glass PNG, a GIF or a PowerPoint magnifier animation. The glass is drawn in the browser - rim, vignette, a specular highlight that trails the direction of travel, and chromatic fringing that strengthens with speed until chromatic={false} turns it off - over live DOM, so it magnifies what your app renders at runtime rather than a picture of it.
Yes. @zyncat/ui/lens ships compiled ESM with its 'use client' directive intact, so it works in the Next.js App Router with no transpilePackages config and no runtime dependencies. Your children are server-rendered and stay in the accessibility tree while the magnified copy is aria-hidden; arrow keys steer the glass and Escape dismisses it once the stage has focus, and under prefers-reduced-motion it settles into place instead of easing.