npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

iv-viewer-ts

v3.0.1

Published

A zooming and panning plugin inspired by google photos for your web images.

Readme

📸 iv-viewer-ts

Modern TypeScript image viewer with Google Photos-like zoom and pan

npm version License: MIT TypeScript Bundle Size Zero Dependencies

DemoDocumentationExamples


✨ Features

  • 🎯 Zero Dependencies - Lightweight and fast
  • 📱 Touch Support - Pinch zoom, double-tap, swipe gestures
  • 🖱️ Mouse Controls - Wheel zoom, click-and-drag panning
  • 🎨 Progressive Loading - Show low-res preview while high-res loads
  • 🗺️ Snap View - Mini-map for easy navigation of zoomed images
  • 📐 Three Modes - Fullscreen, Container, or direct Image enhancement
  • Smooth Animations - Butter-smooth 60fps zoom and pan
  • 🎭 Customizable - Event listeners and configuration options
  • 📦 Multiple Formats - ESM, CommonJS, UMD
  • 🔒 Type-Safe - Full TypeScript support

📦 Installation

npm install iv-viewer-ts
yarn add iv-viewer-ts
pnpm add iv-viewer-ts

🚀 Quick Start

import ImageViewer from 'iv-viewer-ts';
import 'iv-viewer-ts/dist/iv-viewer-ts.css';

const viewer = new ImageViewer('#image-container');
viewer.load('image.jpg', 'high-res-image.jpg');

🎯 Usage Modes

1️⃣ Full-Screen Mode

Perfect for lightbox-style image viewing.

import { FullScreenViewer } from 'iv-viewer-ts';
import 'iv-viewer-ts/dist/iv-viewer-ts.css';

const viewer = new FullScreenViewer();

// Show image in fullscreen
viewer.show('image.jpg', 'high-res-image.jpg');

// Hide when done
viewer.hide();

Use Case: Photo galleries, lightboxes, modal image viewers


2️⃣ Container Mode

Embed the viewer in your own container.

<div id="image-container"></div>
import ImageViewer from 'iv-viewer-ts';
import 'iv-viewer-ts/dist/iv-viewer-ts.css';

const container = document.querySelector('#image-container');
const viewer = new ImageViewer(container, {
  zoomValue: 100,
  maxZoom: 500,
  snapView: true,
});

viewer.load('image.jpg', 'high-res-image.jpg');

Use Case: Custom layouts, dashboards, image editors


3️⃣ Image Mode

Enhance existing <img> elements directly.

<img id="my-image" src="preview.jpg" data-high-res-src="full-quality.jpg" alt="Zoomable image" />
import ImageViewer from 'iv-viewer-ts';
import 'iv-viewer-ts/dist/iv-viewer-ts.css';

const image = document.querySelector('#my-image');
const viewer = new ImageViewer(image);

Use Case: Product images, documentation, blog posts


⚙️ Configuration Options

| Option | Type | Default | Description | | ------------------ | --------- | ------- | --------------------------------- | | zoomValue | number | 100 | Initial zoom percentage (100-500) | | maxZoom | number | 500 | Maximum zoom percentage | | snapView | boolean | true | Show mini-map navigation | | refreshOnResize | boolean | true | Auto-refresh on window resize | | zoomOnMouseWheel | boolean | true | Enable mouse wheel zoom | | hasZoomButtons | boolean | false | Show zoom in/out buttons | | zoomStep | number | 50 | Zoom increment for buttons | | listeners | object | {} | Event callbacks (see below) |

Example with All Options

const viewer = new ImageViewer('#container', {
  zoomValue: 150, // Start at 150% zoom
  maxZoom: 800, // Allow up to 800% zoom
  snapView: true, // Show mini-map
  refreshOnResize: true, // Responsive
  zoomOnMouseWheel: true,
  hasZoomButtons: true,
  zoomStep: 25, // Zoom by 25% per click
  listeners: {
    onInit: (data) => console.log('Initialized', data),
    onImageLoaded: (data) => console.log('Image loaded', data),
    onZoomChange: (data) => console.log('Zoom:', data.zoomValue),
    onImageError: (error) => console.error('Failed to load', error),
    onDestroy: () => console.log('Viewer destroyed'),
  },
});

🎧 Event Listeners

React to viewer state changes with event callbacks:

const viewer = new ImageViewer(element, {
  listeners: {
    // Called when viewer is initialized
    onInit(data) {
      console.log('Viewer ready', data.instance);
    },

    // Called when image successfully loads
    onImageLoaded(data) {
      console.log('Image loaded:', data.container);
    },

    // Called if image fails to load
    onImageError(error) {
      console.error('Load failed:', error);
    },

    // Called whenever zoom changes
    onZoomChange(data) {
      console.log('Zoom:', data.zoomValue);
      console.log('At min zoom:', data.reachedMin);
      console.log('At max zoom:', data.reachedMax);
    },

    // Called when viewer is destroyed
    onDestroy() {
      console.log('Viewer cleaned up');
    },
  },
});

Callback Data Structure

interface CallbackData {
  container: HTMLElement; // Viewer container
  snapView: HTMLElement | null; // Mini-map element (null when snap view is disabled)
  zoomValue: number; // Current zoom (100-500)
  reachedMin: boolean; // At minimum zoom
  reachedMax: boolean; // At maximum zoom
  instance: ImageViewer; // Viewer instance
}

🔧 API Reference

ImageViewer

Constructor

new ImageViewer(element: string | HTMLElement, options?: Options)
  • element: CSS selector string or DOM element (container or <img>)
  • options: Configuration object (see Configuration Options)

Methods

load(imageSrc, hiResImageSrc?)

Load an image into the viewer.

viewer.load('preview.jpg', 'full-resolution.jpg');
  • imageSrc: Low-resolution image (loads immediately)
  • hiResImageSrc (optional): High-resolution image (loads progressively). If you don't have a separate high-res file, pass the same URL as imageSrc.

zoom(percentage, point?)

Programmatically zoom to a specific percentage.

// Zoom to 300%
viewer.zoom(300);

// Zoom to 200% centered at specific point
viewer.zoom(200, { x: 500, y: 300 });
  • percentage: Zoom level (100-maxZoom)
  • point (optional): Center point {x: number, y: number}

resetZoom()

Reset zoom to initial value.

viewer.resetZoom();

refresh()

Recalculate dimensions after container resize.

viewer.refresh();

destroy()

Clean up the viewer and remove all event listeners.

viewer.destroy();

FullScreenViewer

Extends ImageViewer with additional fullscreen methods.

Constructor

new FullScreenViewer(options?: Options)

No element parameter needed - creates its own fullscreen container.


Additional Methods

show(imageSrc, hiResImageSrc?)

Display image in fullscreen mode.

viewer.show('preview.jpg', 'full-resolution.jpg');
  • imageSrc: URL for the initial render.
  • hiResImageSrc (optional): High-resolution URL; reuse imageSrc when you don't have a separate asset.

hide()

Close the fullscreen viewer.

viewer.hide();

🎨 Progressive Image Loading

Improve perceived performance by showing a low-res preview while the high-res version loads in the background.

Container Mode

viewer.load('preview-small.jpg', 'full-resolution.jpg');

FullScreen Mode

viewer.show('preview-small.jpg', 'full-resolution.jpg');

Image Mode

<img src="preview-small.jpg" data-high-res-src="full-resolution.jpg" />

The viewer will:

  1. Display the low-res image immediately
  2. Start loading the high-res image in the background
  3. Progressively update the display as the high-res image loads
  4. Swap to high-res seamlessly when complete

🎮 Gesture Controls

Mouse Controls

  • Drag: Click and drag to pan
  • Wheel: Scroll to zoom in/out
  • Double-click: Toggle between min and max zoom

Touch Controls

  • Swipe: Pan the image
  • Pinch: Pinch in/out to zoom
  • Double-tap: Toggle between min and max zoom

Keyboard Controls

  • Use zoom buttons or programmatic API

📱 Responsive Design

The viewer automatically adapts to container size changes:

// Auto-refresh enabled by default
const viewer = new ImageViewer(container, {
  refreshOnResize: true,
});

// Manual refresh if needed
viewer.refresh();

🎯 Common Use Cases

Photo Gallery with Thumbnails

const viewer = new FullScreenViewer();

document.querySelectorAll('.thumbnail').forEach((thumb) => {
  thumb.addEventListener('click', () => {
    const fullSrc = thumb.dataset.full;
    viewer.show(thumb.src, fullSrc);
  });
});

Product Image Zoom

<img
  class="product-image"
  src="product-400w.jpg"
  data-high-res-src="product-2000w.jpg"
  alt="Product photo"
/>
document.querySelectorAll('.product-image').forEach((img) => {
  new ImageViewer(img, {
    zoomValue: 100,
    maxZoom: 300,
    snapView: false, // Hide mini-map for products
  });
});

Image Editor Integration

const viewer = new ImageViewer('#editor-canvas', {
  listeners: {
    onZoomChange(data) {
      updateZoomIndicator(data.zoomValue);
      toggleZoomButtons(data.reachedMin, data.reachedMax);
    },
  },
});

// External controls
zoomInBtn.onclick = () => viewer.zoom(viewer._state.zoomValue + 50);
zoomOutBtn.onclick = () => viewer.zoom(viewer._state.zoomValue - 50);
resetBtn.onclick = () => viewer.resetZoom();

🌐 Browser Support

  • ✅ Chrome/Edge (latest)
  • ✅ Firefox (latest)
  • ✅ Safari (latest)
  • ✅ Mobile browsers (iOS Safari, Chrome Mobile)
  • ⚠️ IE11 (requires polyfills)

📦 Bundle Formats

// ESM (recommended)
import ImageViewer from 'iv-viewer-ts';

// CommonJS
const ImageViewer = require('iv-viewer-ts').default;

// UMD (browser global)
<script src="node_modules/iv-viewer-ts/dist/iv-viewer-ts.umd.js"></script>
<script>
  const viewer = new window.ImageViewer('#container');
</script>

🔍 TypeScript Support

Full TypeScript definitions included:

import ImageViewer, { FullScreenViewer, ImageViewerOptions } from 'iv-viewer-ts';

const options: ImageViewerOptions = {
  zoomValue: 150,
  maxZoom: 500,
  listeners: {
    onZoomChange: (data) => {
      // Fully typed callback data
      console.log(data.zoomValue);
    },
  },
};

const viewer: ImageViewer = new ImageViewer('#container', options);

🎨 Styling & Customization

Custom CSS

Override default styles with CSS:

/* Custom zoom button colors */
.iv-button-zoom--in,
.iv-button-zoom--out {
  background: #007bff;
  color: white;
}

/* Custom snap view styling */
.iv-snap-view {
  border: 2px solid #007bff;
  border-radius: 8px;
}

/* Custom zoom handle */
.iv-zoom-handle {
  background: #007bff;
}

SCSS Variables

For advanced customization, modify SCSS variables:

$color-1: #222; // Primary color
$color-2: #ccc; // Secondary color
$color-3: #888; // Tertiary color
$color-4: #fff; // Background color
$snap-view-width: 150px; // Mini-map width
$snap-view-height: 150px; // Mini-map height

Then rebuild from source:

npm run build-css

🤝 Contributing

Contributions are welcome! Please see our code review guidelines for development standards.

Development Setup

# Clone repository
git clone https://github.com/bearholmes/iv-viewer-ts.git
cd iv-viewer-ts

# Install dependencies
npm install

# Build
npm run build

# Open examples
open example/index.html

Build Commands

npm run build      # Build all formats + types
npm run type-check # Validate TypeScript without emitting
npm run test:run   # Run unit tests

The build also writes stylesheet outputs to dist/:

  • iv-viewer-ts.css (processed with Autoprefixer)
  • iv-viewer-ts.min.css (Autoprefixer + cssnano for minification)

📄 License

MIT © bearholmes

Original library: iv-viewer by s-yadav


🙏 Credits

This project is a TypeScript fork of the excellent iv-viewer library by @s-yadav.

Improvements in this fork:

  • ✅ Full TypeScript rewrite with strict types
  • ✅ Modern build system (Vite)
  • ✅ ESM + CommonJS + UMD support
  • ✅ Improved event system with error handling
  • ✅ Better documentation and examples
  • ✅ Active maintenance and updates

📚 Resources


Made with ❤️ by bearholmes

⭐ Star this repo if you find it useful!