Skip to main content
This guide documents all configuration options available for each zoom mode, including default values, types, and practical examples.

Wheel Zoom Options

Wheel zoom mode supports the most configuration options, including zoom limits, rotation, and touch gestures.

ZoomImageWheelOptions

type ZoomImageWheelOptions = {
  maxZoom?: number
  wheelZoomRatio?: number
  dblTapAnimationDuration?: number
  initialState?: Partial<ZoomImageWheelStateUpdate>
  shouldZoomOnSingleTouch?: () => boolean
  zoomTarget?: HTMLElement | null
}

maxZoom

maxZoom
number
default:"4"
Maximum zoom level allowed. A value of 4 means 400% zoom.
const result = createZoomImageWheel(container, {
  maxZoom: 6, // Allow up to 600% zoom
});
For high-resolution images, you can increase maxZoom to 8 or higher. For thumbnails or lower-quality images, keep it at 2-3 to avoid pixelation.

wheelZoomRatio

wheelZoomRatio
number
default:"0.1"
Controls how much the zoom level changes per wheel scroll. Higher values mean faster zooming.
const result = createZoomImageWheel(container, {
  wheelZoomRatio: 0.2, // Zoom faster
});

// Or zoom more gradually
const result2 = createZoomImageWheel(container, {
  wheelZoomRatio: 0.05, // Zoom slower for finer control
});

dblTapAnimationDuration

dblTapAnimationDuration
number
default:"300"
Duration in milliseconds for the double-tap zoom animation on touch devices.
const result = createZoomImageWheel(container, {
  dblTapAnimationDuration: 500, // Slower, smoother animation
});

initialState

initialState
Partial<ZoomImageWheelStateUpdate>
Set the initial zoom state, including zoom level and rotation.
const result = createZoomImageWheel(container, {
  initialState: {
    currentZoom: 2, // Start at 200% zoom
    currentRotation: 90, // Rotate 90 degrees
    enable: true, // Zoom enabled by default
  },
});
Available initial state properties:
  • enable: boolean - Whether zoom is enabled
  • currentZoom: number - Initial zoom level (1 = 100%)
  • currentRotation: number - Initial rotation in degrees (0, 90, 180, 270)

shouldZoomOnSingleTouch

shouldZoomOnSingleTouch
() => boolean
default:"() => true"
Function that determines whether single-touch drag should move the zoomed image. Return false to disable single-touch panning.
// Disable single-touch panning (only allow two-finger pinch)
const result = createZoomImageWheel(container, {
  shouldZoomOnSingleTouch: () => false,
});

// Conditional behavior based on zoom level
const result2 = createZoomImageWheel(container, {
  shouldZoomOnSingleTouch: () => {
    return result2.getState().currentZoom > 1;
  },
});
This is particularly useful when you want to prevent conflicts with other touch gestures like scrolling.

zoomTarget

zoomTarget
HTMLElement | null
The element to apply zoom transforms to. By default, it targets the img element inside the container.
// Default behavior: targets the img element
const result = createZoomImageWheel(container);

// Custom target: apply transforms to a wrapper div instead
const customTarget = container.querySelector('.zoom-target');
const result2 = createZoomImageWheel(container, {
  zoomTarget: customTarget,
});

// No target: manually handle transforms
const result3 = createZoomImageWheel(container, {
  zoomTarget: null,
});

result3.subscribe(({ state }) => {
  // Manually apply transforms
  const img = container.querySelector('img');
  img.style.transform = `scale(${state.currentZoom})`;
});

Complete Example

import { createZoomImageWheel } from "@zoom-image/core";

const container = document.getElementById("container");

const result = createZoomImageWheel(container, {
  maxZoom: 8,
  wheelZoomRatio: 0.15,
  dblTapAnimationDuration: 400,
  initialState: {
    currentZoom: 1.5,
    currentRotation: 0,
    enable: true,
  },
  shouldZoomOnSingleTouch: () => true,
  zoomTarget: container.querySelector('img'),
});

// Monitor state changes
result.subscribe(({ state }) => {
  console.log('Zoom:', state.currentZoom);
  console.log('Position:', state.currentPositionX, state.currentPositionY);
  console.log('Rotation:', state.currentRotation);
});

Hover Zoom Options

Hover zoom displays a magnified image in a separate target element.

ZoomImageHoverOptions

type ZoomImageHoverOptions = {
  customZoom: { width: number; height: number }
  zoomImageSource?: string
  zoomLensClass?: string
  zoomLensScale?: number
  zoomTarget: HTMLElement
  zoomTargetClass?: string
  scale?: number
  disableScrollLock?: boolean
  zoomImageProps?: {
    alt?: string
  }
}

customZoom (Required)

customZoom
{ width: number; height: number }
required
Dimensions of the zoomed image display area.
const result = createZoomImageHover(container, {
  zoomTarget: document.getElementById('zoom-target'),
  customZoom: { width: 400, height: 600 },
});

zoomTarget (Required)

zoomTarget
HTMLElement
required
The element where the zoomed image will be displayed.
const zoomTarget = document.getElementById('zoom-target');

const result = createZoomImageHover(container, {
  zoomTarget: zoomTarget,
  customZoom: { width: 300, height: 500 },
});

zoomImageSource

zoomImageSource
string
URL of a higher resolution image to display in the zoom. Defaults to the source image’s src.
const result = createZoomImageHover(container, {
  zoomTarget: target,
  customZoom: { width: 400, height: 600 },
  zoomImageSource: '/images/product-high-res.jpg', // Use high-res version
});
Use a higher resolution image for zoomImageSource to show more detail when zoomed, while keeping the source image smaller for faster initial loading.

scale

scale
number
default:"2"
Magnification factor. A value of 2 means 200% zoom.
const result = createZoomImageHover(container, {
  zoomTarget: target,
  customZoom: { width: 300, height: 500 },
  scale: 3, // 300% magnification
});

zoomLensClass

zoomLensClass
string
CSS class name(s) to apply to the zoom lens element. If not provided, a default semi-transparent background is applied.
const result = createZoomImageHover(container, {
  zoomTarget: target,
  customZoom: { width: 300, height: 500 },
  zoomLensClass: 'custom-lens border-2 border-blue-500',
});
.custom-lens {
  border: 2px solid #6366f1;
  background: rgba(99, 102, 241, 0.2);
  backdrop-filter: blur(2px);
}

zoomLensScale

zoomLensScale
number
default:"1"
Scale factor for the zoom lens size.
const result = createZoomImageHover(container, {
  zoomTarget: target,
  customZoom: { width: 300, height: 500 },
  scale: 2,
  zoomLensScale: 1.5, // Make lens 50% larger
});

zoomTargetClass

zoomTargetClass
string
CSS class name(s) to apply to the zoom target when active.
const result = createZoomImageHover(container, {
  zoomTarget: target,
  customZoom: { width: 300, height: 500 },
  zoomTargetClass: 'active shadow-lg border-gray-300',
});

disableScrollLock

disableScrollLock
boolean
default:"false"
When true, page scrolling is not disabled when hovering over the image.
const result = createZoomImageHover(container, {
  zoomTarget: target,
  customZoom: { width: 300, height: 500 },
  disableScrollLock: true, // Allow page scrolling while zooming
});

zoomImageProps

zoomImageProps
{ alt?: string }
Properties to apply to the zoomed image element.
const result = createZoomImageHover(container, {
  zoomTarget: target,
  customZoom: { width: 300, height: 500 },
  zoomImageProps: {
    alt: 'Zoomed view of product',
  },
});

Complete Example

import { createZoomImageHover } from "@zoom-image/core";

const container = document.getElementById("hover-container");
const zoomTarget = document.getElementById("zoom-target");

const result = createZoomImageHover(container, {
  zoomTarget: zoomTarget,
  customZoom: { width: 400, height: 600 },
  zoomImageSource: '/images/product-4k.jpg',
  scale: 2.5,
  zoomLensClass: 'lens-custom border-2 border-indigo-500',
  zoomLensScale: 1.2,
  zoomTargetClass: 'zoom-active shadow-xl',
  disableScrollLock: false,
  zoomImageProps: {
    alt: 'Magnified product view',
  },
});

// Monitor loading state
result.subscribe(({ state }) => {
  console.log('Zoom image status:', state.zoomedImgStatus);
});

Move Zoom Options

Move zoom displays a magnified image that follows the cursor.

ZoomImageMoveOptions

type ZoomImageMoveOptions = {
  zoomFactor?: number
  zoomImageSource?: string
  disabledContextMenu?: boolean
  zoomImageProps?: {
    alt?: string
    className?: string
  }
}

zoomFactor

zoomFactor
number
default:"4"
Magnification factor. A value of 4 means 400% zoom.
const result = createZoomImageMove(container, {
  zoomFactor: 6, // 600% magnification
});

zoomImageSource

zoomImageSource
string
URL of a higher resolution image to display when zoomed. Defaults to the source image’s src.
const result = createZoomImageMove(container, {
  zoomImageSource: '/images/product-high-res.jpg',
  zoomFactor: 4,
});

disabledContextMenu

disabledContextMenu
boolean
default:"false"
When true, disables the context menu (right-click menu) on the zoomed image and prevents long-press image saving on mobile.
const result = createZoomImageMove(container, {
  zoomFactor: 4,
  disabledContextMenu: true, // Prevent right-click and long-press
});
This applies -webkit-user-select: none, -webkit-touch-callout: none, and oncontextmenu = () => false to the zoomed image.

zoomImageProps

zoomImageProps
{ alt?: string; className?: string }
Properties to apply to the zoomed image element.
const result = createZoomImageMove(container, {
  zoomFactor: 4,
  zoomImageProps: {
    alt: 'Magnified view',
    className: 'zoomed-img rounded shadow-lg',
  },
});

Complete Example

import { createZoomImageMove } from "@zoom-image/core";

const container = document.getElementById("move-container");

const result = createZoomImageMove(container, {
  zoomFactor: 5,
  zoomImageSource: '/images/product-ultra-hd.jpg',
  disabledContextMenu: true,
  zoomImageProps: {
    alt: 'High resolution product zoom',
    className: 'zoom-img-custom',
  },
});

// Monitor state
result.subscribe(({ state }) => {
  if (state.zoomedImgStatus === 'loading') {
    console.log('Loading high-res image...');
  } else if (state.zoomedImgStatus === 'loaded') {
    console.log('High-res image loaded!');
  }
});

Click Zoom Options

Click zoom activates on click and follows the cursor until clicked again.

ZoomImageClickOptions

type ZoomImageClickOptions = {
  zoomFactor?: number
  zoomImageSource?: string
  disableScrollLock?: boolean
  zoomImageProps?: {
    alt?: string
  }
}

zoomFactor

zoomFactor
number
default:"4"
Magnification factor. A value of 4 means 400% zoom.
const result = createZoomImageClick(container, {
  zoomFactor: 5, // 500% magnification
});

zoomImageSource

zoomImageSource
string
URL of a higher resolution image to display when zoomed. Defaults to the source image’s src.
const result = createZoomImageClick(container, {
  zoomImageSource: '/images/product-high-res.jpg',
  zoomFactor: 4,
});

disableScrollLock

disableScrollLock
boolean
default:"false"
When true, page scrolling is not disabled when the zoom is active.
const result = createZoomImageClick(container, {
  zoomFactor: 4,
  disableScrollLock: true, // Allow scrolling while zoomed
});

zoomImageProps

zoomImageProps
{ alt?: string }
Properties to apply to the zoomed image element.
const result = createZoomImageClick(container, {
  zoomFactor: 4,
  zoomImageProps: {
    alt: 'Click zoom view',
  },
});

Complete Example

import { createZoomImageClick } from "@zoom-image/core";

const container = document.getElementById("click-container");

const result = createZoomImageClick(container, {
  zoomFactor: 6,
  zoomImageSource: '/images/product-4k.jpg',
  disableScrollLock: false,
  zoomImageProps: {
    alt: 'Click-activated zoom view',
  },
});

// Monitor state
result.subscribe(({ state }) => {
  console.log('Image status:', state.zoomedImgStatus);
});

Common State Properties

All zoom modes return an object with methods to interact with the state.

Return Value Methods

cleanup
() => void
Removes all event listeners and cleans up the zoom instance.
subscribe
(callback: (state) => void) => () => void
Subscribes to state changes. Returns an unsubscribe function.
getState
() => State
Returns the current state object.
setState
(newState: StateUpdate) => void
Updates the state (only available for wheel and hover modes).

State Objects by Mode

Wheel Zoom State

type ZoomImageWheelState = {
  currentRotation: number      // Current rotation in degrees
  currentZoom: number          // Current zoom level (1 = 100%)
  enable: boolean              // Whether zoom is enabled
  currentPositionX: number     // X position of the zoomed image
  currentPositionY: number     // Y position of the zoomed image
}

Hover Zoom State

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

Move Zoom State

type ZoomImageMoveState = {
  zoomedImgStatus: ZoomedImgStatus  // "idle" | "loading" | "loaded" | "error"
}

Click Zoom State

type ZoomImageClickState = {
  zoomedImgStatus: ZoomedImgStatus  // "idle" | "loading" | "loaded" | "error"
}

Option Dependencies

Some options work together or affect each other:
In hover zoom mode, scale determines the magnification level, while zoomLensScale controls the size of the lens overlay. They work together to create the zoom effect:
createZoomImageHover(container, {
  scale: 2,          // 200% magnification
  zoomLensScale: 1,  // Normal lens size
  customZoom: { width: 400, height: 600 },
});
The lens size is calculated as: (customZoom.width / scale) * zoomLensScale
If you set initialState.currentZoom higher than maxZoom, it will be clamped to maxZoom:
createZoomImageWheel(container, {
  maxZoom: 4,
  initialState: {
    currentZoom: 6, // Will be clamped to 4
  },
});
When using a different zoomImageSource, the library loads this image asynchronously. Monitor the loading state:
const result = createZoomImageMove(container, {
  zoomImageSource: '/large-image.jpg',
});

result.subscribe(({ state }) => {
  // States: "idle" -> "loading" -> "loaded" | "error"
  console.log(state.zoomedImgStatus);
});

Next Steps

Advanced Usage

Learn advanced patterns and techniques

API Reference

Detailed API documentation

Build docs developers (and LLMs) love