
Simple pan/zoom solution for SVGs in HTML. It adds events listeners for mouse scroll, double-click and pan, plus it optionally offers: * JavaScript API for control of pan and zoom behavior * onPan and onZoom event handlers * On-screen zoom controls
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: - Share it so we can get directly to the problem. You can use this starter jsfiddle setup to provide your example. Or upload your own jsfiddle.net (or any other live) example. - Mention your library version (located in library file in header) - Mention your browser name, version and operating system - Mention any other important for debug details
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:
* Fork this repository
* Clone repository fork (created in previous step) locally (on your machine)
* Ensure that you have nodejs and npm installed locally
* In console:
* cd into project folder
* Run npm install
* Run npm install -g gulp if you don't have it already installed globally
* Running gulp will listen for source files changes (in src folder) and will automatically build distribution files
* Running gulp compile will compile source files
* Running gulp check will check syntax and automatically fix some errors
* Running gulp test will run tests
* Running gulp build will prepare the project for a new release
* Implement the change using gulp or gulp compile
* After change is done test it with gulp check and gulp test
* Commit only meaningful changes. Do not commit distribution files (dist folder). Distribution files are built only before a release
* Push your changes into your fork
* Create a pull request
Pan and zoom the SVG tiger on github pages:
* Single Inline SVG
* Multiple Inline SVGs
* SVG Inserted with Embed Element
* SVG Inserted with Object Element
* SVG Inserted with Img Element (These cannot be panned/zoomed.)
* SVG With custom controls
* Resize SVG container on document resize
* Two SVGs with synchronized zooming and panning
* Custom events: Touch events support: pan, double tap, pinch
* Custom events: Enable zooming only on click, disable on mouse out
* Limit pan
* Dynamic SVG load
* Using Require.js
* Pan animation
* Zooming just one SVG layer
* Thumbnail Viewer
Reference the svg-pan-zoom.js file from your HTML document. Then call the init method:
var panZoomTiger = svgPanZoom('#demo-tiger');
// or
var svgElement = document.querySelector('#demo-tiger')
var 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:
svgPanZoom('#demo-tiger', {
viewportSelector: '.svg-pan-zoom_viewport'
, panEnabled: true
, controlIconsEnabled: false
, zoomEnabled: true
, dblClickZoomEnabled: true
, mouseWheelZoomEnabled: true
, preventMouseEventsDefault: true
, zoomScaleSensitivity: 0.2
, minZoom: 0.5
, maxZoom: 10
, fit: true
, contain: false
, center: true
, refreshRate: 'auto'
, beforeZoom: function(){}
, onZoom: function(){}
, beforePan: function(){}
, onPan: function(){}
, onUpdatedCTM: function(){}
, customEventsHandler: {}
, eventsListenerElement: null
});
If any arguments are specified, they must have the following value types:
* 'viewportSelector' can be querySelector string or SVGElement.
* 'panEnabled' must be true or false. Default is true.
* 'controlIconsEnabled' must be true or false. Default is false.
* 'zoomEnabled' must be true or false. Default is true.
* 'dblClickZoomEnabled' must be true or false. Default is true.
* 'mouseWheelZoomEnabled' must be true or false. Default is true.
* 'preventMouseEventsDefault' must be true or false. Default is true.
* 'zoomScaleSensitivity' must be a scalar. Default is 0.2.
* 'minZoom' must be a scalar. Default is 0.5.
* 'maxZoom' must be a scalar. Default is 10.
* 'fit' must be true or false. Default is true.
* 'contain' must be true or false. Default is false.
* 'center' must be true or false. Default is true.
* 'refreshRate' must be a number or 'auto'
* 'beforeZoom' must be a callback function to be called before zoom changes.
* 'onZoom' must be a callback function to be called when zoom changes.
* 'beforePan' must be a callback function to be called before pan changes.
* 'onPan' must be a callback function to be called when pan changes.
* 'customEventsHandler' must be an object with init and destroy arguments as functions.
* 'eventsListenerElement' must be an SVGElement or null.
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 form inside of
beforeZoom,onZoom,beforePanandonPancallbacks 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
<embed type="image/svg+xml" src="https://github.com/bumbu/svg-pan-zoom/raw/3.6.1/path/to/my/file.svg" />
<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:
<embed type="image/svg+xml" src="https://github.com/bumbu/svg-pan-zoom/raw/3.6.1/path/to/my/file.svg" id="my-embed"/>
<script>
document.getElementById('my-embed').addEventListener('load', function(){
// Will get called after embed element was loaded
svgPanZoom(document.getElementById('my-embed'));
})
</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:
* There is just one top-level graphical element of type SVGGElement (<g>)
* SVGGElement has no transform attribute
* There is no other SVGGElement with class name svg-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:
<g class="svg-pan-zoom_viewport">
<g transform="matrix(1,0,0,1,0,0);"></g>
</g>
You can specify your own viewport selector by altering viewportSelector config value:
svgPanZoom('#demo-tiger', {
viewportSelector: '.svg-pan-zoom_viewport'
});
// or
var viewportGroupElement = document.getElementById('demo-tiger').querySelector('.svg-pan-zoom_viewport');
svgPanZoom('#demo-tiger', {
viewportSelector: viewportGroupElement
});
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:
* Add the package as node module npm install --save ariutta/svg-pan-zoom
* Require svg-pan-zoom in your source file svgPanZoom = require('svg-pan-zoom')
* Use in the same way as you would do with global svgPanZoom: 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 strings
* init: function
* destroy: function
haltEventListeners 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 - SVGSVGElement
* instance - svg-pan-zoom public API instance
destroy is a function called upon svg-pan-zoom destroy
An example of how to use it together with Hammer.js:
var options = {
zoomEnabled: true
, controlIconsEnabled: true
, customEventsHandler: {
// Halt all touch events
haltEventListeners: ['touchstart', 'touchend', 'touchmove', 'touchleave', 'touchcancel']
// Init custom events handler
, init: function(options) {
// Init Hammer
this.hammer = Hammer(options.svgElement)
// Handle double tap
this.hammer.on('doubletap', function(ev){
options.instance.zoomIn()
})
}
// Destroy custom events handler
, destroy: function(){
this.hammer.destroy()
}
}
}
svgPanZoom('#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:
* enablePan
* disablePan
* isPanEnabled
* pan
* panBy
* getPan
* setBeforePan
* setOnPan
* enableZoom
* disableZoom
* isZoomEnabled
* enableControlIcons
* disableControlIcons
* isControlIconsEnabled
* enableDblClickZoom
* disableDblClickZoom
* isDblClickZoomEnabled
* enableMouseWheelZoom
* disableMouseWheelZoom
* isMouseWheelZoomEnabled
* setZoomScaleSensitivity
* setMinZoom
* setMaxZoom
* setBeforeZoom
* setOnZoom
* zoom
* zoomBy
* zoomAtPoint
* zoomAtPointBy
* zoomIn
* zoomOut
* setOnUpdatedCTM
* getZoom
* resetZoom
* resetPan
* reset
* fit
* contain
* center
* updateBBox
* resize
* getSizes
* destroy
To programmatically pan, ca
$ claude mcp add svg-pan-zoom \
-- python -m otcore.mcp_server <graph>