Demos

Image gallery with zoom

The zoom plugin adds every way of zooming an image in a lightbox: pinch on touch screens, double tap or double click for actual size, zoom in and zoom out buttons, and drag to pan once zoomed. The rotate plugin adds rotate and flip beside it. All the settings are in the zoom and rotate references.

Demo

Open a photo and zoom in: pinch on a phone, double click on a desktop, or use the zoom buttons in the toolbar. Drag the zoomed image to pan.

HTML

<div id="image-zoom-gallery">
    <a href="img/img1.jpg" data-lg-size="1600-2400">
        <img src="img/thumb1.jpg" alt="Close-up of an eye" />
    </a>
    <a href="img/img2.jpg" data-lg-size="1600-1067">
        <img src="img/thumb2.jpg" alt="Dew on a leaf" />
    </a>
    <!-- more items -->
</div>

JavaScript

import lightGallery from 'lightgallery';
import lgRotate from 'lightgallery/plugins/rotate';
import lgThumbnail from 'lightgallery/plugins/thumbnail';
import lgZoom from 'lightgallery/plugins/zoom';

lightGallery(document.getElementById('image-zoom-gallery'), {
    plugins: [lgZoom, lgRotate, lgThumbnail],
    // Zoom in and zoom out buttons next to the actual-size button; the
    // library shows only actual size by default.
    showZoomInOutIcons: true,
    actualSize: true,
    // How much each zoom-in or zoom-out step changes the scale.
    scale: 1,
});
import { LightGallery, LightGalleryItem } from '@lightgallery/react';
import Rotate from '@lightgallery/react/plugins/rotate';
import Thumbnail from '@lightgallery/react/plugins/thumbnail';
import Zoom from '@lightgallery/react/plugins/zoom';

const items = [
    {
        src: 'img/img1.jpg',
        thumb: 'img/thumb1.jpg',
        alt: 'Close-up of an eye',
        lgSize: '1600-2400',
    },
    {
        src: 'img/img2.jpg',
        thumb: 'img/thumb2.jpg',
        alt: 'Dew on a leaf',
        lgSize: '1600-1067',
    },
];

// Zoom in and zoom out buttons next to the actual-size button; the
// library shows only actual size by default. `scale` is how much each
// step changes the scale.
<LightGallery
    plugins={[Zoom, Rotate, Thumbnail]}
    zoom={{ showZoomInOutIcons: true, actualSize: true, scale: 1 }}
>
    {items.map((item) => (
        <LightGalleryItem key={item.src} item={item} href={item.src}>
            <img src={item.thumb} alt={item.alt} />
        </LightGalleryItem>
    ))}
</LightGallery>;
<script setup>
import { LightGallery, LgItem } from '@lightgallery/vue';
import Rotate from '@lightgallery/vue/plugins/rotate';
import Thumbnail from '@lightgallery/vue/plugins/thumbnail';
import Zoom from '@lightgallery/vue/plugins/zoom';

const plugins = [Zoom, Rotate, Thumbnail];
const items = [
    {
        src: 'img/img1.jpg',
        thumb: 'img/thumb1.jpg',
        alt: 'Close-up of an eye',
        lgSize: '1600-2400',
    },
    {
        src: 'img/img2.jpg',
        thumb: 'img/thumb2.jpg',
        alt: 'Dew on a leaf',
        lgSize: '1600-1067',
    },
];
</script>

<template>
    <!-- Zoom in and zoom out buttons next to the actual-size button; the
         library shows only actual size by default. `scale` is how much
         each step changes the scale. -->
    <LightGallery
        :plugins="plugins"
        :zoom="{ showZoomInOutIcons: true, actualSize: true, scale: 1 }"
    >
        <LgItem v-for="item of items" :key="item.src" :item="item">
            <img :src="item.thumb" :alt="item.alt" />
        </LgItem>
    </LightGallery>
</template>
import { Component } from '@angular/core';
import {
    LgGalleryComponent,
    LgGalleryItemDirective,
    type LgGalleryItem,
} from '@lightgallery/angular';
import { withRotate } from '@lightgallery/angular/plugins/rotate';
import { withThumbnail } from '@lightgallery/angular/plugins/thumbnail';
import { withZoom } from '@lightgallery/angular/plugins/zoom';

@Component({
    selector: 'app-gallery',
    imports: [LgGalleryComponent, LgGalleryItemDirective],
    template: `
        <lg-gallery [features]="features">
            @for (item of items; track item.src) {
                <a [href]="item.src" [lgGalleryItem]="item">
                    <img [src]="item.thumb" [alt]="item.alt" />
                </a>
            }
        </lg-gallery>
    `,
})
export class Gallery {
    // Zoom in and zoom out buttons next to the actual-size button; the
    // library shows only actual size by default. `scale` is how much
    // each step changes the scale.
    features = [
        withZoom({ showZoomInOutIcons: true, actualSize: true, scale: 1 }),
        withRotate(),
        withThumbnail(),
    ];

    items: LgGalleryItem[] = [
        {
            src: 'img/img1.jpg',
            thumb: 'img/thumb1.jpg',
            alt: 'Close-up of an eye',
            lgSize: '1600-2400',
        },
        {
            src: 'img/img2.jpg',
            thumb: 'img/thumb2.jpg',
            alt: 'Dew on a leaf',
            lgSize: '1600-1067',
        },
    ];
}

How zooming works

InputWhat happens
Pinch on a touch screenZooms around the point between the fingers; the image follows the fingers while they move
Double tap, or double click with a mouseSwitches between the fitted size and the image’s actual pixel size, centred on the tap
Zoom in and zoom out buttonsChange the scale by scale per press; off by default, showZoomInOutIcons turns them on
Actual size buttonSame as a double tap, from the toolbar
Drag with one finger or the mousePans a zoomed image; it springs back inside its edges when released
Pinch inwards on an un-zoomed imageCloses the gallery, like a photos app; pinchToClose turns it off
Rotate and flip buttonsFrom the rotate plugin; zoom keeps working on a rotated image
Moving to another slideResets the zoom, so every slide opens fitted to the screen

The toolbar buttons are ordinary buttons, so a keyboard user reaches them with Tab and presses them with Enter or Space.

Zoom works on image slides. Video and iframe slides keep their own controls and the zoom buttons do nothing on them.

Settings

Zoom plugin settings, passed at the top level of the settings object in vanilla JavaScript and as the zoom prop or withZoom() options in the framework packages:

SettingDefaultMeaning
zoomtrueEnables the plugin’s zoom behaviour; false keeps the plugin loaded but inert
scale1Amount added to or removed from the scale by each zoom-in or zoom-out step
infiniteZoomtrueLets zoom-in go past the image’s actual pixel size
actualSizetrueShows the actual-size button
showZoomInOutIconsfalseShows the zoom-in and zoom-out buttons
enableZoomAfter300Milliseconds after the slide transition before zoom styles are applied, so an opening animation and the zoom transforms never fight

The core setting pinchToClose (default true) is what makes an inward pinch close the gallery; it needs the zoom plugin and closable.

Rotate plugin settings: rotate, rotateSpeed (default 400 ms), rotateLeft, rotateRight, flipHorizontal and flipVertical, each button on by default.

Does zoom need the image dimensions?

No. Zoom works from the loaded image. The data-lg-size attribute (lgSize on an item) is for the open-from-thumbnail animation, which the zoom from origin demo covers, and the actual-size button uses the loaded image’s natural size.

Can the zoomed image be larger than the file?

Yes when infiniteZoom is on, which is the default; the browser scales the pixels up. For a product shot that must stay sharp when zoomed, serve the largest file you have as src and let responsive loading pick smaller variants for small screens.

For a zoom that happens in place, without a lightbox, see the Medium-style zoom demo.

Edit this page on GitHub