Gathering detailed insights and metrics for svg-pan-zoom
Gathering detailed insights and metrics for svg-pan-zoom
Gathering detailed insights and metrics for svg-pan-zoom
Gathering detailed insights and metrics for svg-pan-zoom
JavaScript library that enables panning and zooming of an SVG in an HTML document, with mouse events or custom JavaScript hooks
npm install svg-pan-zoom
96.2
Supply Chain
99.6
Quality
83.1
Maintenance
100
Vulnerability
100
License
v3.6.1 Update deps. Use Prettier.
Published on 21 Sept 2019
v3.6.0 Passive mouse events listeners
Published on 07 Oct 2018
v3.5.2 Better handling of multitouch panning
Published on 26 Jul 2017
v3.5.1 Small fixes
Published on 08 May 2017
v3.5.0
Published on 15 Mar 2017
v3.4.1 Update ts definitions
Published on 16 Jan 2017
Module System
Min. Node Version
Typescript Support
Node Version
NPM Version
1,762 Stars
408 Commits
389 Forks
53 Watching
11 Branches
35 Contributors
Updated on 25 Nov 2024
Minified
Minified + Gzipped
JavaScript (97%)
CSS (1.23%)
HTML (0.91%)
TypeScript (0.85%)
Cumulative downloads
Total Downloads
Last day
-2.5%
62,962
Compared to previous day
Last week
1.9%
336,124
Compared to previous week
Last month
9.2%
1,412,281
Compared to previous month
Last year
251.8%
12,281,047
Compared to previous year
Simple pan/zoom solution for SVGs in HTML. It adds events listeners for mouse scroll, double-click and pan, plus it optionally offers:
It works cross-browser and supports both inline SVGs and SVGs in HTML object
or embed
elements.
If you're looking for version 2.3.x you can find it in v2.3.x branch
If you found a bug or have a suggestion first check if there is a similar open or closed issue. If there are none then create a new one.
When opening a new issue please provide a reproducible example:
If you solved a bug or implemented a feature that may be useful for others then you're welcome to create a pull request.
If you have any other type of questions, problems, your code is not working or you want to critique the library - you can use StackOverflow. Just tag your question with svgpanzoom
.
Best way to contribute is to create a pull request. In order to create a pull request:
cd
into project foldernpm install
npm install -g gulp
if you don't have it already installed globallygulp
will listen for source files changes (in src
folder) and will automatically build distribution filesgulp compile
will compile source filesgulp check
will check syntax and automatically fix some errorsgulp test
will run testsgulp build
will prepare the project for a new releasegulp
or gulp compile
gulp check
and gulp test
dist
folder). Distribution files are built only before a releasePan and zoom the SVG tiger on github pages:
Embed
ElementObject
ElementImg
Element (These cannot be panned/zoomed.)Reference the svg-pan-zoom.js file from your HTML document. Then call the init method:
1var panZoomTiger = svgPanZoom('#demo-tiger'); 2// or 3var svgElement = document.querySelector('#demo-tiger') 4var panZoomTiger = svgPanZoom(svgElement)
First argument to function should be a CSS selector of SVG element or a DOM Element.
If you want to override the defaults, you can optionally specify one or more arguments:
1svgPanZoom('#demo-tiger', { 2 viewportSelector: '.svg-pan-zoom_viewport' 3, panEnabled: true 4, controlIconsEnabled: false 5, zoomEnabled: true 6, dblClickZoomEnabled: true 7, mouseWheelZoomEnabled: true 8, preventMouseEventsDefault: true 9, zoomScaleSensitivity: 0.2 10, minZoom: 0.5 11, maxZoom: 10 12, fit: true 13, contain: false 14, center: true 15, refreshRate: 'auto' 16, beforeZoom: function(){} 17, onZoom: function(){} 18, beforePan: function(){} 19, onPan: function(){} 20, onUpdatedCTM: function(){} 21, customEventsHandler: {} 22, eventsListenerElement: null 23});
If any arguments are specified, they must have the following value types:
init
and destroy
arguments as functions.beforeZoom
will be called with 2 float attributes: oldZoom and newZoom.
If beforeZoom
will return false
then zooming will be halted.
onZoom
callbacks will be called with one float attribute representing new zoom scale.
beforePan
will be called with 2 attributes:
oldPan
newPan
Each of these objects has two attributes (x and y) representing current pan (on X and Y axes).
If beforePan
will return false
or an object {x: true, y: true}
then panning will be halted.
If you want to prevent panning only on one axis then return an object of type {x: true, y: false}
.
You can alter panning on X and Y axes by providing alternative values through return {x: 10, y: 20}
.
Caution! If you alter panning by returning custom values
{x: 10, y: 20}
it will update only current pan step. If panning is done by mouse/touch you have to take in account that next pan step (after the one that you altered) will be performed with values that do not consider altered values (as they even did not existed).
onPan
callback will be called with one attribute: newPan
.
Caution! Calling zoom or pan API methods from inside of
beforeZoom
,onZoom
,beforePan
andonPan
callbacks may lead to infinite loop.
onUpdatedCTM
will get called after the CTM will get updated. That happens asynchronously from pan and zoom events.
panEnabled
and zoomEnabled
are related only to user interaction. If any of this options are disabled - you still can zoom and pan via API.
fit
takes precedence over contain
. So if you set fit: true
then contain
's value doesn't matter.
If you're embedding a remote file like this
1<embed type="image/svg+xml" src="/path/to/my/file.svg" /> 2<object type="image/svg+xml" data="/path/to/my/file.svg">Your browser does not support SVG</object>
or you're rendering the SVG after the page loads then you'll have to call svgPanZoom library after your SVG is loaded.
One way to do so is by listening to load event:
1<embed type="image/svg+xml" src="/path/to/my/file.svg" id="my-embed"/>
2
3<script>
4document.getElementById('my-embed').addEventListener('load', function(){
5 // Will get called after embed element was loaded
6 svgPanZoom(document.getElementById('my-embed'));
7})
8</script>
You may want to use a custom viewport if you have more layers in your SVG but you want to pan-zoom only one of them.
By default if:
<g>
)transform
attributesvg-pan-zoom_viewport
then the top-level graphical element will be used as viewport.
To specify which layer (SVGGElement) should be pan-zoomed set the svg-pan-zoom_viewport
class name to that element:
<g class="svg-pan-zoom_viewport"></g>
.
Do not set any transform attributes to that element. It will make the library misbehave. If you need transform attribute for viewport better create a nested group element and set transforms to that element:
1<g class="svg-pan-zoom_viewport"> 2 <g transform="matrix(1,0,0,1,0,0);"></g> 3</g>
You can specify your own viewport selector by altering viewportSelector
config value:
1svgPanZoom('#demo-tiger', {
2 viewportSelector: '.svg-pan-zoom_viewport'
3});
4// or
5var viewportGroupElement = document.getElementById('demo-tiger').querySelector('.svg-pan-zoom_viewport');
6svgPanZoom('#demo-tiger', {
7 viewportSelector: viewportGroupElement
8});
If you want to listen for user interaction events from a child SVG element then use eventsListenerElement
option. An example is available in demo/layers.html.
To use with browserify, follow these steps:
npm install --save bumbu/svg-pan-zoom
svgPanZoom = require('svg-pan-zoom')
instance = svgPanZoom('#demo-tiger')
An example of how to load library using Require.js is available in demo/require.html
You may want to add custom events support (for example double tap or pinch).
It is possible by setting customEventsHandler
configuration option.
customEventsHandler
should be an object with following attributes:
haltEventListeners
: array of stringsinit
: functiondestroy
: functionhaltEventListeners
specifies which default event listeners should be disabled (in order to avoid conflicts as svg-pan-zoom by default supports panning using touch events).
init
is a function that is called when svg-pan-zoom is initialized. An object is passed into this function.
Passed object has following attributes:
svgElement
- SVGSVGElementinstance
- svg-pan-zoom public API instancedestroy
is a function called upon svg-pan-zoom destroy
An example of how to use it together with Hammer.js:
1var options = { 2 zoomEnabled: true 3, controlIconsEnabled: true 4, customEventsHandler: { 5 // Halt all touch events 6 haltEventListeners: ['touchstart', 'touchend', 'touchmove', 'touchleave', 'touchcancel'] 7 8 // Init custom events handler 9 , init: function(options) { 10 // Init Hammer 11 this.hammer = Hammer(options.svgElement) 12 13 // Handle double tap 14 this.hammer.on('doubletap', function(ev){ 15 options.instance.zoomIn() 16 }) 17 } 18 19 // Destroy custom events handler 20 , destroy: function(){ 21 this.hammer.destroy() 22 } 23 } 24} 25 26svgPanZoom('#mobile-svg', options);
You may find an example that adds support for Hammer.js pan, pinch and doubletap in demo/mobile.html
You may want to keep SVG content visible by not allowing panning over SVG borders.
To do so you may prevent or alter panning from beforePan
callback. For more details take a look at demo/limit-pan.html
example.
When you call svgPanZoom
method it returns an object with following methods:
To programmatically pan, call the pan method with vector as first argument:
1// Get instance 2var panZoomTiger = svgPanZoom('#demo-tiger'); 3 4// Pan to rendered point x = 50, y = 50 5panZoomTiger.pan({x: 50, y: 50}) 6 7// Pan by x = 50, y = 50 of rendered pixels 8panZoomTiger.panBy({x: 50, y: 50})
To programmatically zoom, you can use the zoom method to specify your desired scale value:
1// Get instance
2var panZoomTiger = svgPanZoom('#demo-tiger');
3
4// Set zoom level to 2
5panZoomTiger.zoom(2)
6
7// Zoom by 130%
8panZoomTiger.zoomBy(1.3)
9
10// Set zoom level to 2 at point
11panZoomTiger.zoomAtPoint(2, {x: 50, y: 50})
12
13// Zoom by 130% at given point
14panZoomTiger.zoomAtPointBy(1.3, {x: 50, y: 50})
Zoom is relative to initial SVG internal zoom level. If your SVG was fit at the beginning (option
fit: true
) and thus zoomed in or out to fit available space - initial scale will be 1 anyway.
Or you can use the zoomIn or zoomOut methods:
1// Get instance 2var panZoomTiger = svgPanZoom('#demo-tiger'); 3 4panZoomTiger.zoomIn() 5panZoomTiger.zoomOut() 6panZoomTiger.resetZoom()
If you want faster or slower zooming, you can override the default zoom increment with the setZoomScaleSensitivity method.
To programmatically enable/disable pan or zoom:
1// Get instance 2var panZoomTiger = svgPanZoom('#demo-tiger'); 3 4panZoomTiger.enablePan(); 5panZoomTiger.disablePan(); 6 7panZoomTiger.enableZoom(); 8panZoomTiger.disableZoom();
To fit and center (you may try contain
instead of fit
):
1// Get instance 2var panZoomTiger = svgPanZoom('#demo-tiger'); 3 4panZoomTiger.fit(); 5panZoomTiger.center();
If you want to fit and center your SVG after its container resize:
1// Get instance 2var panZoomTiger = svgPanZoom('#demo-tiger'); 3 4panZoomTiger.resize(); // update SVG cached size and controls positions 5panZoomTiger.fit(); 6panZoomTiger.center();
If you update SVG (viewport) contents so its border box (virtual box that contains all elements) changes, you have to call updateBBox
:
1var panZoomTiger = svgPanZoom('#demo-tiger'); 2panZoomTiger.fit(); 3 4// Update SVG rectangle width 5document.getElementById('demo-tiger').querySelector('rect').setAttribute('width', 200) 6 7// fit does not work right anymore as viewport bounding box changed 8panZoomTiger.fit(); 9 10panZoomTiger.updateBBox(); // Update viewport bounding box 11panZoomTiger.fit(); // fit works as expected
If you need more data about SVG you can call getSizes
. It will return an object that will contain:
width
- SVG cached widthheight
- SVG cached heightrealZoom
- a and d attributes of transform matrix applied over viewportviewBox
- an object containing cached sizes of viewport boxder box
width
height
x
- x offsety
- y offsetDestroy SvgPanZoom instance:
1// Get instance 2var panZoomTiger = svgPanZoom('#demo-tiger'); 3 4panZoomTiger.destroy(); 5delete panZoomTiger;
Before committing you should check your code style by running gulp check
.
If you made a change then first build the library. Open ./tests/index.html
in your browser. All tests should pass.
If you have PhantomJS installed then you can run gulp test
.
Because the library removes viewBox
attribute from the SVG element - you may experience that the height of your SVG changed (usually to 150px). In order to fix that you have to add height to the SVG
or object
/embed
.
This library does not support working with SVGs that are hidden as some browsers detach child documents from the DOM when those are hidden. See #279 for more details.
If performance is bad only on initialization of the library, then consider wrapping all SVG's child elements into a <g>
beforehand. This way the library will not have to create it and move all children into it (which is the root cause of the issue). See #146 comment.
Most often those are caused by big SVG files. And in those cases it's browsers not being able to handle those SVGs fast enough. See #277 for more details.
For zooming there is minZoom
and maxZoom
zoom config options.
For panning and custom zoom experiences take a look at limit-pan example.
Currently there're 2 ways of doing animation: via CSS or programatically - see #101 for more details.
object
/embed
or dynamically loaded SVGsYou have to ensure that the SVG is loaded and available in DOM before initializing the library.
Check dymanic-load demo.
You can use jsdelivr as a CDN. It supports automatic pulling from NPM and GitHub.
For example use https://cdn.jsdelivr.net/npm/svg-pan-zoom@3.5.0/dist/svg-pan-zoom.min.js
to load version 3.5.0
.
For more usage examples check jsdelivr usage.
This library used the SVGPan library as a starting point. SVGPan is intended for use with the SVG 'script' element, whereas svg-pan-zoom is intended for use with the HTML 'script' element.
Wrapper Libraries (feel free to add to this -- pull requests welcome!)
The code from the SVGPan library is licensed under the following BSD license:
Copyright 2009-2010 Andrea Leofreddi <a.leofreddi@vleo.net>. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list
of conditions and the following disclaimer in the documentation and/or other materials
provided with the distribution.
THIS SOFTWARE IS PROVIDED BY Andrea Leofreddi "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Andrea Leofreddi OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* The views and conclusions contained in the software and documentation are those of the
authors and should not be interpreted as representing official policies, either expressed
or implied, of Andrea Leofreddi.
The code from the updates and changes to SVGPan are licensed under the same BSD license, with the copyright for the code from each change held by the author of that code.
No vulnerabilities found.
Reason
no binaries found in the repo
Reason
license file detected
Details
Reason
Found 7/15 approved changesets -- score normalized to 4
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
Reason
project is not fuzzed
Details
Reason
branch protection not enabled on development/release branches
Details
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
Reason
14 existing vulnerabilities detected
Details
Score
Last Scanned on 2024-11-25
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More