Module provides for image zooming and positioning with use of gestures on a touch screen.
Find a file
Claude 76949aaf48
docs: Convert all diagrams to Mermaid.js with GitHub dark mode colors
Updated all text-based diagrams to use Mermaid.js syntax with colors
optimized for GitHub dark mode viewing.

Changes:
- QUICK_REFERENCE.md: 2 diagrams converted
  • Data Flow (graph LR with color-coded stages)
  • Touch Event Flow (flowchart TD with detailed state tracking)

- ARCHITECTURE.md: 6 diagrams converted
  • High-Level Architecture (graph TB with subgraphs)
  • Complete User Interaction Flow (sequenceDiagram)
  • Signal Reactivity Flow (flowchart TD)
  • Gesture Detection State Machine (stateDiagram-v2)
  • Component Lifecycle (flowchart TD with feedback loops)
  • Event Listener Lifecycle (flowchart TD)

- docs/README.md: 3 diagrams converted
  • The Big Picture (flowchart TD)
  • Component Hierarchy (graph TD)
  • Data Flow (flowchart TD)

Color Palette (GitHub dark mode optimized):
- Blue (#58a6ff): Logic, calculations, core functions
- Green (#3fb950): Success states, event handlers, initialization
- Yellow/Orange (#d29922): Computed signals, state updates
- Purple (#a371f7): User actions, signals, reactivity
- Pink (#db61a2): Events, callbacks, emissions
- Red (#f85149): DOM updates, destruction, browser events

Benefits:
 Interactive diagrams render on GitHub
 Consistent color coding across all documentation
 Better readability in dark mode
 Professional visual presentation
 Easier to understand complex flows
2025-11-15 15:41:12 +00:00
docs docs: Convert all diagrams to Mermaid.js with GitHub dark mode colors 2025-11-15 15:41:12 +00:00
projects/ngx-pinch-zoom docs: Add comprehensive maintainer documentation 2025-11-15 15:22:38 +00:00
src feat: Upgrade to Angular 20 with signals and comprehensive modernization 2025-11-15 14:18:05 +00:00
.editorconfig migrated protractor to cypress 2022-02-07 12:52:32 +01:00
.gitignore added .angular to gitignore and fixed unit test 2022-02-07 12:20:00 +01:00
.prettierignore added prettier 2022-02-07 12:01:23 +01:00
.prettierrc format all files with prettier 2022-02-07 13:46:52 +01:00
angular.json feat: Upgrade to Angular 20 with signals and comprehensive modernization 2025-11-15 14:18:05 +00:00
CHANGELOG.md feat: Upgrade to Angular 20 with signals and comprehensive modernization 2025-11-15 14:18:05 +00:00
CONTRIBUTING.md feat: Upgrade to Angular 20 with signals and comprehensive modernization 2025-11-15 14:18:05 +00:00
LICENSE Create LICENSE 2019-12-07 21:24:22 +03:00
package-lock.json feat: Upgrade to Angular 20 with signals and comprehensive modernization 2025-11-15 14:18:05 +00:00
package.json feat: Upgrade to Angular 20 with signals and comprehensive modernization 2025-11-15 14:18:05 +00:00
README.md feat: Upgrade to Angular 20 with signals and comprehensive modernization 2025-11-15 14:18:05 +00:00
tsconfig.app.json feat: Upgrade to Angular 20 with signals and comprehensive modernization 2025-11-15 14:18:05 +00:00
tsconfig.json feat: Upgrade to Angular 20 with signals and comprehensive modernization 2025-11-15 14:18:05 +00:00

ngx-pinch-zoom

Angular TypeScript

An Angular library for pinch-to-zoom functionality on touch-enabled devices and mouse interactions. Built with Angular 20+ and modern signals API.

Features

  • 🎯 Angular 20+ with Signals - Modern reactive programming
  • 📱 Touch & Mouse Support - Works on all devices
  • 🔄 Pinch to Zoom - Natural gesture support
  • 🖱️ Mouse Wheel Zoom - Desktop-friendly
  • 👆 Double Tap - Quick zoom in/out
  • 🎨 Highly Configurable - Extensive options
  • 📦 Standalone Component - No module imports needed
  • Performance Optimized - Uses signals for reactivity

Installation

npm install @meddv/ngx-pinch-zoom

Quick Start

1. Import the Component

import { Component } from '@angular/core';
import { PinchZoomComponent } from '@meddv/ngx-pinch-zoom';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [PinchZoomComponent],
  template: `
    <pinch-zoom>
      <img src="path/to/image.jpg" alt="Zoomable image" />
    </pinch-zoom>
  `
})
export class AppComponent {}

2. Add Viewport Meta Tag

For proper touch support, add this to your index.html:

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no">

Usage Examples

Basic Usage

<pinch-zoom>
  <img src="image.jpg" />
</pinch-zoom>

With Configuration (Using Signals)

import { Component, signal } from '@angular/core';
import { PinchZoomComponent } from '@meddv/ngx-pinch-zoom';

@Component({
  selector: 'app-example',
  standalone: true,
  imports: [PinchZoomComponent],
  template: `
    <pinch-zoom
      [transitionDuration]="200"
      [doubleTap]="true"
      [limitZoom]="3"
      [autoZoomOut]="false"
      [disabled]="isDisabled()"
      (zoomChanged)="onZoomChange($event)">
      <img src="image.jpg" />
    </pinch-zoom>
  `
})
export class ExampleComponent {
  isDisabled = signal(false);

  onZoomChange(scale: number) {
    console.log('Current zoom level:', scale);
  }
}

Programmatic Control

import { Component, viewChild } from '@angular/core';
import { PinchZoomComponent } from '@meddv/ngx-pinch-zoom';

@Component({
  selector: 'app-controls',
  standalone: true,
  imports: [PinchZoomComponent],
  template: `
    <pinch-zoom #pinchZoom>
      <img src="image.jpg" />
    </pinch-zoom>

    <button (click)="zoomIn()">Zoom In</button>
    <button (click)="zoomOut()">Zoom Out</button>
    <button (click)="reset()">Reset</button>
  `
})
export class ControlsComponent {
  pinchZoom = viewChild<PinchZoomComponent>('pinchZoom');

  zoomIn() {
    this.pinchZoom()?.zoomIn(0.5);
  }

  zoomOut() {
    this.pinchZoom()?.zoomOut(0.5);
  }

  reset() {
    this.pinchZoom()?.toggleZoom();
  }
}

Configuration Options

Input Type Default Description
transitionDuration number 200 Animation duration in milliseconds
doubleTap boolean true Enable double-tap to zoom
doubleTapScale number 2 Scale factor for double-tap zoom
autoZoomOut boolean false Automatically reset zoom after pinch
limitZoom number | 'original image size' 'original image size' Maximum zoom level
minScale number 0 Minimum allowed scale
disabled boolean false Disable all zoom functionality
disablePan boolean false Disable panning with one finger
disableZoomControl 'disable' | 'never' | 'auto' 'auto' Control zoom button visibility
overflow 'hidden' | 'visible' 'hidden' CSS overflow behavior
zoomControlScale number 1 Scale factor for zoom controls
backgroundColor string 'rgba(0,0,0,0.85)' Container background color
limitPan boolean false Prevent panning past image edges
minPanScale number 1.0001 Minimum scale at which panning is enabled
listeners 'auto' | 'mouse and touch' 'mouse and touch' Event listener mode
wheel boolean true Enable mouse wheel zoom
wheelZoomFactor number 0.2 Zoom factor for mouse wheel
autoHeight boolean false Calculate height from image dimensions
draggableImage boolean false Make image draggable
draggableOnPinch boolean false Allow dragging while pinching

Outputs

Output Type Description
zoomChanged OutputEmitterRef<number> Emits current scale when zoom changes

Methods

Access these methods via template reference or viewChild:

Method Parameters Returns Description
toggleZoom() - void Toggle between zoomed in/out
zoomIn(value) value: number number Zoom in by value, returns new scale
zoomOut(value) value: number number Zoom out by value, returns new scale
destroy() - void Clean up event listeners

Computed Properties

The component exposes several computed signals:

Property Type Description
scale() number Current zoom scale
isZoomedIn() boolean Whether image is zoomed in
isDisabled() boolean Whether zoom is disabled
isDragging() boolean Whether user is currently dragging
isZoomLimitReached() boolean Whether max zoom is reached
maxScale() number Maximum allowed scale
isControl() boolean Whether zoom controls should be shown

Angular 20 Signals

This library fully embraces Angular 20's signals API:

Input Signals

All component inputs are now signal-based for better performance and reactivity.

// Before (Angular <16)
@Input() disabled: boolean = false;

// Now (Angular 20+)
disabled = input<boolean>(false);

Output Signals

Outputs use the new output() API:

// Before
@Output() zoomChanged = new EventEmitter<number>();

// Now
zoomChanged = output<number>();

Computed Signals

Derived state uses computed signals:

isZoomedIn = computed<boolean>(() => {
  return this.scale() > 1;
});

Browser Support

  • Chrome/Edge (latest 2 versions)
  • Firefox (latest 2 versions)
  • Safari (latest 2 versions)
  • iOS Safari (latest 2 versions)
  • Chrome for Android (latest 2 versions)

Requirements

  • Angular 20.0.0 or higher
  • TypeScript 5.8.0 or higher
  • Node.js 18.19.1, 20.11.1, or 22.0.0+

Migration from Older Versions

If you're upgrading from a pre-signals version:

  1. Inputs: No changes needed in templates, binding syntax remains the same
  2. Outputs: Event binding syntax remains the same
  3. ViewChild: Update to viewChild signal (optional but recommended)
  4. Component properties: Access computed properties by calling them: component.scale()

Contributing

See CONTRIBUTING.md for development setup and guidelines.

License

MIT

Credits

This project was forked and modernized for Angular 19/20 compatibility.

Original library: ngx-pinch-zoom

Issues and Support

Please report issues on GitHub Issues