• Stars
    star
    1,570
  • Rank 28,697 (Top 0.6 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created about 8 years ago
  • Updated 11 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Universal pan and zoom library (DOM, SVG, Custom)

panzoom build status

Extensible, mobile friendly pan and zoom framework (supports DOM and SVG).

Demo

Usage

Grab it from npm and use with your favorite bundler:

npm install panzoom --save

Or download from CDN:

<script src='https://unpkg.com/[email protected]/dist/panzoom.min.js'></script>

If you download from CDN the library will be available under panzoom global name.

Pan and zoom DOM subtree

// just grab a DOM element
var element = document.querySelector('#scene')

// And pass it to panzoom
panzoom(element)

SVG panzoom example

<!-- this is your html file with svg -->
<body>
  <svg>
    <!-- this is the draggable root -->
    <g id='scene'> 
      <circle cx='10' cy='10' r='5' fill='pink'></circle>
    </g>
  </svg>
</body>
// In the browser panzoom is already on the
// window. If you are in common.js world, then 
// var panzoom = require('panzoom')

// grab the DOM SVG element that you want to be draggable/zoomable:
var element = document.getElementById('scene')

// and forward it it to panzoom.
panzoom(element)

If require a dynamic behavior (e.g. you want to make an element not draggable anymore, or even completely delete an SVG element) make sure to call dispose() method:

var instance = panzoom(element)
// do work
// ...
// then at some point you decide you don't need this anymore:
instance.dispose()

This will make sure that all event handlers are cleared and you are not leaking memory

Events notification

The library allows to subscribe to transformation changing events. E.g. when user starts/ends dragging the element, the element will fire panstart/panend events. Here is example of all supported events:

var instance = panzoom(element);
instance.on('panstart', function(e) {
  console.log('Fired when pan is just started ', e);
  // Note: e === instance.
});

instance.on('pan', function(e) {
  console.log('Fired when the `element` is being panned', e);
});

instance.on('panend', function(e) {
  console.log('Fired when pan ended', e);
});

instance.on('zoom', function(e) {
  console.log('Fired when `element` is zoomed', e);
});

instance.on('zoomend', function(e) {
  console.log('Fired when zoom animation ended', e);
});

instance.on('transform', function(e) {
  // This event will be called along with events above.
  console.log('Fired when any transformation has happened', e);
});

See JSFiddle console for a demo.

Ignore mouse wheel

Sometimes zooming interferes with scrolling. If you want to alleviate it you can provide a custom filter, which will allow zooming only when modifier key is down. E.g.

panzoom(element, {
  beforeWheel: function(e) {
    // allow wheel-zoom only if altKey is down. Otherwise - ignore
    var shouldIgnore = !e.altKey;
    return shouldIgnore;
  }
});

See JSFiddle for the demo. The tiger will be zoomable only when Alt key is down.

Ignore mouse down

If you want to disable panning or filter it by pressing a specific key, use the beforeMouseDown() option. E.g.

panzoom(element, {
  beforeMouseDown: function(e) {
    // allow mouse-down panning only if altKey is down. Otherwise - ignore
    var shouldIgnore = !e.altKey;
    return shouldIgnore;
  }
});

Note that it only works when the mouse initiates the panning and would not work for touch initiated events.

Ignore keyboard events

By default, panzoom will listen to keyboard events, so that users can navigate the scene with arrow keys and +, - signs to zoom out. If you don't want this behavior you can pass the filterKey() predicate that returns truthy value to prevent panzoom's default behavior:

panzoom(element, {
  filterKey: function(/* e, dx, dy, dz */) {
    // don't let panzoom handle this event:
    return true;
  }
});

Zoom Speed

You can adjust how fast it zooms, by passing optional zoomSpeed argument:

panzoom(element, {
  zoomSpeed: 0.065 // 6.5% per mouse wheel event
});

Pinch Speed

On touch devices zoom is achieved by "pinching" and depends on distance between two fingers. We try to match the zoom speed with pinch, but if you find that too slow (or fast), you can adjust it:

panzoom(element, {
  pinchSpeed: 2 // zoom two times faster than the distance between fingers
});

Get current transform (scale, offset)

To get the current zoom (scale) level use the getTransform() method:

console.log(instance.getTransform()); // prints {scale: 1.2, x: 10, y: 10}

Fixed transform origin when zooming

By default when you use mouse wheel or pinch to zoom, panzoom uses mouse coordinates to determine the central point of the zooming operation.

If you want to override this behavior and always zoom into center of the screen pass transformOrigin to the options:

panzoom(element, {
  // now all zoom operations will happen based on the center of the screen
  transformOrigin: {x: 0.5, y: 0.5}
});

You specify transformOrigin as a pair of {x, y} coordinates. Here are some examples:

// some of the possible values:
let topLeft = {x: 0, y: 0};
let topRight = {x: 1, y: 0};
let bottomLeft = {x: 0, y: 1};
let bottomRight = {x: 1, y: 1};
let centerCenter = {x: 0.5, y: 0.5};

// now let's use it:
panzoom(element, {
  transformOrigin: centerCenter
});

To get or set new transform origin use the following API:

let instance = panzoom(element, {
  // now all zoom operations will happen based on the center of the screen
  transformOrigin: {x: 0.5, y: 0.5}
});

let origin = instance.getTransformOrigin(); // {x: 0.5, y: 0.5}

instance.setTransformOrigin({x: 0, y: 0}); // now it is topLeft
instance.setTransformOrigin(null); // remove transform origin

Min Max Zoom

You can set min and max zoom, by passing optional minZoom and maxZoom argument:

var instance = panzoom(element, {
  maxZoom: 1,
  minZoom: 0.1
});

You can later get the values using getMinZoom() and getMaxZoom()

assert(instance.getMaxZoom() === 1);
assert(instance.getMinZoom() === 0.1);

Disable Smooth Scroll

You can disable smooth scroll, by passing optional smoothScroll argument:

panzoom(element, {
  smoothScroll: false
});

With this setting the momentum is disabled.

Pause/resume the panzoom

You can pause and resume the panzoom by calling the following methods:

var element = document.getElementById('scene');
var instance = panzoom(element);

instance.isPaused(); //  returns false
instance.pause();    //  Pauses event handling
instance.isPaused(); //  returns true now
instance.resume();   //  Resume panzoom
instance.isPaused(); //  returns false again

Script attachment

If you want to quickly play with panzoom without using javascript, you can configure it via script tag:

<!-- this is your html file -->
<!DOCTYPE html>
<html>
<head>
  <script src='https://unpkg.com/[email protected]/dist/panzoom.min.js'
    query='#scene' name='pz'></script>
</head>
<body>
  <svg>
    <!-- this is the draggable root -->
    <g id='scene'> 
      <circle cx='10' cy='10' r='5' fill='pink'></circle>
    </g>
  </svg>
</body>
</html>

Most importantly, you can see query attribute that points to CSS selector. Once the element is found panzoom is attached to this element. The controller will become available under window.pz name. And you can pass additional options to the panzoom via attributes prefixed with pz-.

Here is a demo: Script based attributes

Adjust Double Click Zoom

You can adjust the double click zoom multiplier, by passing optional zoomDoubleClickSpeed argument.

When double clicking, zoom is multiplied by zoomDoubleClickSpeed, which means that a value of 1 will disable double click zoom completely.

panzoom(element, {
  zoomDoubleClickSpeed: 1, 
});

Set Initial Position And Zoom

You can set the initial position and zoom, by chaining the zoomAbs function with x position, y position and zoom as arguments:

panzoom(element, {
  maxZoom: 1,
  minZoom: 0.1,
  initialX: 300,
  initialY: 500,
  initialZoom: 0.5
});

Handling touch events

The library will handle ontouch events very aggressively, it will preventDefault, and stopPropagation for the touch events inside container. Sometimes this is not a desirable behavior.

If you want to take care about this yourself, you can pass onTouch callback to the options object:

panzoom(element, {
  onTouch: function(e) {
    // `e` - is current touch event.

    return false; // tells the library to not preventDefault.
  }
});

Note: if you don't preventDefault yourself - make sure you test the page behavior on iOS devices. Sometimes this may cause page to bounce undesirably.

Handling double click events

By default panzoom will prevent default action on double click events - this is done to avoid accidental text selection (which is default browser action on double click). If you prefer to allow default action, you can pass onDoubleClick() callback to options. If this callback returns false, then the library will not prevent default action:

panzoom(element, {
  onDoubleClick: function(e) {
    // `e` - is current double click event.

    return false; // tells the library to not preventDefault, and not stop propagation
  }
});

Bounds on Panzoom

By default panzoom will not prevent Image from Panning out of the Container. bounds (boolean) and boundsPadding (number) can be defined so that it doesn't fall out. Default value for boundsPadding is 0.05 .

panzoom(element, {
  bounds: true,
  boundsPadding: 0.1
});

Triggering Pan

To Pan the object using Javascript use moveTo(<number>,<number>) function. It expects x, y value to where to move.

instance.moveTo(0, 0);

To pan in a smooth way use smoothMoveTo(<number>,<number>):

instance.smoothMoveTo(0, 0);

Triggering Zoom

To Zoom the object using Javascript use zoomTo(<number>,<number>,<number>) function. It expects x, y value as coordinates of where to zoom. It also expects the zoom factor as the third argument. If zoom factor is greater than 1, apply zoom IN. If zoom factor is less than 1, apply zoom OUT.

instance.zoomTo(0, 0, 2);

To zoom in a smooth way use smoothZoom(<number>,<number>,<number>):

instance.smoothZoom(0, 0, 0.5);

Custom UI to trigger zoom

One of the common use case is to have a custom UI to trigger zoom. For example, you can use a button to zoom in/out. Since this library does not depend on any popular framework (react, vue, etc.) you can implement it yourself following this example:

license

MIT

More Repositories

1

city-roads

Visualization of all roads within any city
JavaScript
5,402
star
2

VivaGraphJS

Graph drawing library for JavaScript
JavaScript
3,646
star
3

ngraph.path

Path finding in a graph
JavaScript
2,801
star
4

atree

Just a simple Christmas tree, based on reddit story
JavaScript
2,424
star
5

pm

package managers visualization
JavaScript
1,408
star
6

ngraph

Beautiful Graphs
1,360
star
7

npmgraph.an

2d visualization of npm
JavaScript
1,160
star
8

fieldplay

A vector field explorer
JavaScript
1,108
star
9

sayit

Visualization of related subreddits
JavaScript
937
star
10

vs

Visualization of Google's autocomplete
JavaScript
919
star
11

word2vec-graph

Exploring word2vec embeddings as a graph of nearest neighbors
Python
691
star
12

time

Simple Google Sheets interface to track time
JavaScript
623
star
13

peak-map

Make a ridge line chart from any region on Earth
JavaScript
583
star
14

graph-drawing-libraries

Trying to compare known graph drawing libraries
JavaScript
571
star
15

map-of-reddit

Interactive map of reddit
JavaScript
540
star
16

common-words

visualization of common words in different programming languages
JavaScript
495
star
17

ngraph.graph

Graph data structure in JavaScript
JavaScript
463
star
18

ngraph.pixel

Fast graph renderer based on low level ShaderMaterial from three.js
JavaScript
295
star
19

npmrank

npm dependencies graph metrics
JavaScript
280
star
20

streamlines

Streamlines calculator
JavaScript
275
star
21

isect

Segments intersection detection library
JavaScript
253
star
22

gauss-distribution

A fun little project to show distribution of pixels in Gauss's portrait
HTML
249
star
23

oflow

Optical flow detection in JavaScript
JavaScript
200
star
24

ghindex

Creates github index for similar repositories discovery
JavaScript
189
star
25

gazer

GitHub analysis and discovery
JavaScript
186
star
26

git-also

For a `file` in your git repository, prints other files that are most often committed together
JavaScript
185
star
27

allnpmviz3d

3d visualization of npm
JavaScript
179
star
28

ngraph.path.demo

This is a demo project for ngraph.path
JavaScript
165
star
29

map-of-github

Inspirational Mapping
Vue
157
star
30

ngraph.forcelayout

Force directed graph layout
JavaScript
146
star
31

pixchart

Turn any image into delightful splash of colors and order
JavaScript
112
star
32

city-script

Collection of scripts that can be loaded into city-roads
JavaScript
112
star
33

yasiv-youtube

Graph of related videos from YouTube
JavaScript
100
star
34

winvelviz

Wind visualization over time
JavaScript
100
star
35

query-state

Application state in query string
JavaScript
97
star
36

e-sum

Visualization of exponential sums
JavaScript
97
star
37

ngraph.forcelayout3d

Force directed graph layout in 3d
JavaScript
95
star
38

index-large-cities

A simple indexer of road networks from OSM. Data for @anvaka/city-roads
JavaScript
92
star
39

graph-start

a simple graph shell to explore ideas
JavaScript
88
star
40

greview

Books that I read and their neighborhoods
86
star
41

lsystem

A simple L-Systems explorer powered by WebGL
JavaScript
86
star
42

jsruntime

Chrome Extension to explore javascript runtime.
JavaScript
85
star
43

map-of-reddit-data

Contains scripts and data to render map of reddit
JavaScript
82
star
44

redsim

reddit discovery
JavaScript
82
star
45

w-gl

A simple WebGL renderer
TypeScript
80
star
46

pplay

Create, play and share pixels. Online WebGL shader editor.
GLSL
76
star
47

ngraph.hde

High dimensional embedding of a graph and its layout
JavaScript
76
star
48

dotparser

Parser of GraphViz dot file format
PEG.js
72
star
49

wind-lines

Streamline animation of wind data
JavaScript
63
star
50

set-vs-object

What is faster Set or Object?
JavaScript
62
star
51

three.map.control

A three.js camera that mimics 2d maps navigation with pan and zoom
JavaScript
53
star
52

ngraph.native

C++ implementation of force-based layout from ngraph
C++
49
star
53

circles

A simple spirograph toy
JavaScript
49
star
54

yaot

Yet another octree
JavaScript
48
star
55

ngraph.three

3D graph renderer powered by three.js
JavaScript
44
star
56

ngraph.generators

Graph generators
JavaScript
42
star
57

citations

Most cited papers by keyword
C++
42
star
58

rafor

requestAnimationFrame friendly async for iterator
JavaScript
41
star
59

ngraph.fabric

Fabric.js graph renderer
JavaScript
38
star
60

playground

Just a set of experiments that I want to play with, but they are too small to be in their own repository
JavaScript
35
star
61

ngraph.centrality

Module to calculate graph centrality metrics
JavaScript
33
star
62

streak

Streak tracking with Google Sheets
JavaScript
33
star
63

sayit-data

data with similar subreddits graph
JavaScript
32
star
64

ngraph.offline.layout

Performs offline layout of large graphs and saves results to the disk
JavaScript
32
star
65

cord-19

exploring research papers about coronaviruses
JavaScript
31
star
66

how-to-debug-node-js-addons

How to debug node.js addons in xcode
30
star
67

wheel

Mouse wheel event unified for all browsers
JavaScript
30
star
68

npmgraphbuilder

Builds graph of npm dependencies from npm registry
JavaScript
29
star
69

generator-n

minimalistic node package yeoman generator
JavaScript
28
star
70

tiny.xml

Tiny (1.6KB) in-browser xml parser
JavaScript
27
star
71

allgithub

Crawling github data
JavaScript
27
star
72

mars

Map of Mars
JavaScript
26
star
73

ngraph.pixi

PIXI.js graph renderer
JavaScript
26
star
74

ngraph.pagerank

PageRank calculation for ngraph.graph
JavaScript
25
star
75

noisylines

Tracking noise with streamlines
JavaScript
23
star
76

ngraph.physics.simulator

Physics library for ngraph
JavaScript
23
star
77

nb

Neighborhood beautification: Graph layout through message passing
JavaScript
23
star
78

strangeb

The strangest thing happens when you rotate Bezier control points
JavaScript
22
star
79

graph-to-vector-field

Converts a graph into vector field texture
JavaScript
20
star
80

amator

Tiny animation library
JavaScript
20
star
81

ngraph.louvain

Given a graph instance detects communities using the Louvain Method
JavaScript
20
star
82

npmgraph

Visualization of NPM dependencies
JavaScript
19
star
83

similar-cities

Visualization of cities with similar road networks
JavaScript
19
star
84

allnpm

Graph generator for entire npm registry
JavaScript
18
star
85

twitter-recommended-graph

Building a proposal for Twitter to show a map of recommended people
JavaScript
18
star
86

streaming-svg-parser

Streaming SVG/XML parser with zero dependencies
JavaScript
18
star
87

extract-osm-roads

A simple utility to fetch a city graph from OSM
JavaScript
18
star
88

rules-of-ml

A simple visualization of Martin Zinkevich article
JavaScript
17
star
89

quadtree.cc

A C++ implementation of quadtree
C++
17
star
90

ngraph.events

Events support in ngraph.*
JavaScript
17
star
91

simplegrad

Simple reverse mode automatic differentiation of scalar values in javascript
JavaScript
16
star
92

portrait

Portrait of quotes
JavaScript
16
star
93

sunburst

For a given tree builds an SVG based SunBurst diagram
JavaScript
15
star
94

local-chat

Local instance of ChatGPT for my kiddo
HTML
15
star
95

what-people-google

Visualization of what people google
JavaScript
15
star
96

vuereddit

A simple reddit client written as a vue component.
Vue
14
star
97

ngraph.fromjson

Library to load graph from simple json format
JavaScript
12
star
98

color-high

A demo of ngraph.forcelayout in 6D space
JavaScript
12
star
99

color-force-vis

Visualizing forces acting on nodes during force layout
JavaScript
11
star
100

allnpmviz.an

Visualization of entire npm
JavaScript
11
star