iv-viewer-ts
v3.0.1
Published
A zooming and panning plugin inspired by google photos for your web images.
Maintainers
Readme
📸 iv-viewer-ts
Modern TypeScript image viewer with Google Photos-like zoom and pan
Demo • Documentation • Examples
✨ 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-tsyarn add iv-viewer-tspnpm 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
imageSrcwhen 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:
- Display the low-res image immediately
- Start loading the high-res image in the background
- Progressively update the display as the high-res image loads
- 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 heightThen 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.htmlBuild Commands
npm run build # Build all formats + types
npm run type-check # Validate TypeScript without emitting
npm run test:run # Run unit testsThe 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!
