Skip to main content

Overview

createZoomImageHover creates a lens-based zoom effect where hovering over an image displays a magnified portion in a separate zoom target area. This is commonly used in e-commerce product galleries.

Function Signature

function createZoomImageHover(
  container: HTMLElement,
  options: ZoomImageHoverOptions
): {
  cleanup: () => void
  subscribe: (listener: Listener) => () => void
  getState: () => ZoomImageHoverState
  setState: (value: ZoomImageHoverStateUpdate) => void
}

Parameters

container
HTMLElement
required
The HTML element that contains the source image. The function will automatically find the first <img> element inside this container.
options
ZoomImageHoverOptions
required
Configuration options for the hover zoom behavior.
options.customZoom
{ width: number; height: number }
required
The dimensions of the zoom window where the magnified image will be displayed.
options.zoomTarget
HTMLElement
required
The container element where the zoomed image will be rendered. This should be a separate element from the source image container.
options.zoomImageSource
string
The URL of a higher-resolution image to display in the zoom area. Defaults to the source image’s src attribute.
options.zoomLensClass
string
CSS class names to apply to the zoom lens (the overlay that follows the cursor). If not provided, a default pink semi-transparent background is applied.
options.zoomLensScale
number
default:"1"
Scale factor for the zoom lens size. Smaller values create a bigger zoomed image with a smaller lens. Must be positive.
options.zoomTargetClass
string
CSS class names to add to the zoom target element when zooming is active. Useful for styling transitions or borders.
options.scale
number
default:"2"
The magnification scale of the zoomed image. A value of 2 means 2x magnification.
options.disableScrollLock
boolean
default:"false"
If true, page scrolling will not be locked when hovering over the image on touch devices.
options.zoomImageProps
object
Additional properties for the zoomed image element.
options.zoomImageProps.alt
string
Alt text for the zoomed image element.

Return Value

Returns an object with the following methods:
cleanup
() => void
Removes all event listeners, zoom lens, and zoomed image elements. Call this when the component unmounts.
subscribe
(listener: Listener) => () => void
Subscribe to state changes. The listener is called when the zoomed image loading status or enabled state changes. Returns an unsubscribe function.
type Listener = (state: ZoomImageHoverState, prevState: ZoomImageHoverState) => void
getState
() => ZoomImageHoverState
Get the current state including the zoomed image loading status and enabled state.
setState
(value: ZoomImageHoverStateUpdate) => void
Update the state to enable or disable the zoom functionality.

State Types

ZoomImageHoverState

type ZoomImageHoverState = {
  zoomedImgStatus: ZoomedImgStatus  // "idle" | "loading" | "loaded" | "error"
  enabled: boolean                   // Whether zoom is currently enabled
}

ZoomImageHoverStateUpdate

type ZoomImageHoverStateUpdate = {
  enabled: boolean  // Enable or disable zoom functionality
}

ZoomedImgStatus

type ZoomedImgStatus = "idle" | "loading" | "loaded" | "error"

Usage Examples

Basic Usage

import { createZoomImageHover } from '@zoom-image/core'

const container = document.getElementById('image-container')
const zoomTarget = document.getElementById('zoom-area')

const { cleanup } = createZoomImageHover(container, {
  customZoom: { width: 500, height: 500 },
  zoomTarget: zoomTarget
})

// Call cleanup when done
cleanup()

With High-Resolution Image

const { cleanup } = createZoomImageHover(container, {
  customZoom: { width: 600, height: 600 },
  zoomTarget: zoomTarget,
  zoomImageSource: '/images/product-high-res.jpg',
  scale: 3
})

Custom Lens Styling

// CSS
.custom-lens {
  border: 2px solid #007bff;
  background: rgba(0, 123, 255, 0.2);
  cursor: crosshair;
}

// JavaScript
const { cleanup } = createZoomImageHover(container, {
  customZoom: { width: 500, height: 500 },
  zoomTarget: zoomTarget,
  zoomLensClass: 'custom-lens',
  zoomTargetClass: 'zoom-active',
  zoomLensScale: 0.8
})

Subscribe to Loading State

const { cleanup, subscribe } = createZoomImageHover(container, {
  customZoom: { width: 500, height: 500 },
  zoomTarget: zoomTarget,
  zoomImageSource: '/images/large.jpg'
})

const unsubscribe = subscribe((state, prevState) => {
  if (state.zoomedImgStatus === 'loading') {
    console.log('Loading high-res image...')
  } else if (state.zoomedImgStatus === 'loaded') {
    console.log('High-res image loaded!')
  } else if (state.zoomedImgStatus === 'error') {
    console.error('Failed to load high-res image')
  }
})

// Cleanup
unsubscribe()
cleanup()

Toggle Zoom Functionality

const { setState, getState } = createZoomImageHover(container, {
  customZoom: { width: 500, height: 500 },
  zoomTarget: zoomTarget
})

// Disable zoom
setState({ enabled: false })

// Re-enable zoom
setState({ enabled: true })

// Check current state
const state = getState()
console.log('Enabled:', state.enabled)
console.log('Image status:', state.zoomedImgStatus)
<div class="product-gallery">
  <div id="product-image" style="position: relative; width: 400px; height: 400px;">
    <img src="product-thumb.jpg" alt="Product" />
  </div>
  <div id="product-zoom" style="width: 600px; height: 600px; border: 1px solid #ddd;"></div>
</div>
const container = document.getElementById('product-image')
const zoomTarget = document.getElementById('product-zoom')

const { cleanup } = createZoomImageHover(container, {
  customZoom: { width: 600, height: 600 },
  zoomTarget: zoomTarget,
  zoomImageSource: 'product-full.jpg',
  scale: 2.5,
  zoomLensScale: 1,
  disableScrollLock: false
})

Features

  • Lens-based zoom: Visual lens overlay shows which area is being magnified
  • Separate zoom area: Magnified view appears in a dedicated target element
  • High-res support: Load a different, higher-resolution image for the zoom view
  • Lazy loading: Zoomed image only loads when user hovers
  • Loading states: Track image loading progress via state subscription
  • Customizable styling: Apply custom CSS classes to lens and zoom target
  • Scroll lock: Prevents page scrolling during touch interactions (optional)

Source Reference

Implementation: /packages/core/src/createZoomImageHover.ts:27

Build docs developers (and LLMs) love