svg-pan-zoom-gesture
v0.0.2
Published
Pan and zoom for SVG images
Downloads
62
Maintainers
Readme
svg-pan-zoom-gesture
Small JS library to add pan and zoom functionality to SVG (inline or image). It supports gestures for all types of devices:
| intention | mouse | trackpad/touchpad | touchscren | | --------- | ----------------------- | ----------------- | --------------- | | pan | clik + move | click + move | two finger drag | | zoom | Ctrl + wheel | pinch | pinch | | reset | double click | double click | double tap | | | | | | | scroll | wheel | two finger drag | one finger drag |
Pay attention:
- gestures intentionally selected to not interfere with the system's default scroll gestures, to avoid "scroll traps"
- all actions are available through gestures, so it works without UI. You can add UI, though. Library exposes methods for this, like
pan(dx, dy)
andzoom(scale)
Demo
Usage
There are two flavors:
- Headless - without UI
- Default UI
Headless
If you have container element in HTML:
import { SvgPanZoom } from "svg-pan-zoom-gesture";
document.querySelectorAll(".svg-pan-zoom").forEach((container) => {
const element = container.querySelector("svg,img");
if (!element) return;
new SvgPanZoom({ element, container }).on();
});
If you don't have container element in HTML:
import { SvgPanZoom } from "svg-pan-zoom-gesture";
document.querySelectorAll("svg").forEach((element) => {
const container = document.createElement("div");
container.className = "svg-pan-zoom";
element.replaceWith(container);
container.append(element);
new SvgPanZoom({ element, container }).on();
});
Additionally following CSS is required:
.svg-pan-zoom {
overflow: hidden;
touch-action: pan-x pan-y;
user-select: none;
cursor: grab;
}
.svg-pan-zoom svg,
.svg-pan-zoom img {
/* need to center smaller images or fix bug in zoom functionality */
margin: auto;
/* need to fit bigger images */
max-width: 100%;
height: auto;
}
.svg-pan-zoom img {
pointer-events: none;
}
Instance methods:
on()
- adds event listenersoff()
- removes event listenerspan(dx, dy)
- pans imagezoom(scale)
- zooms imagereset()
- resets pan and zoom values
Default UI
import "svg-pan-zoom-gesture/css/SvgPanZoomUi.css";
import { SvgPanZoomUi } from "svg-pan-zoom-gesture";
document.querySelectorAll(".svg-pan-zoom").forEach((container) => {
const element = container.querySelector("svg,img");
if (!element) return;
new SvgPanZoomUi({ element, container }).on();
});
Additionally, CSS to style UI required (for example with Tailwind):
.svg-pan-zoom .buttons {
@apply inline-flex;
}
.svg-pan-zoom .zoom-in {
@apply bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded-l;
}
.svg-pan-zoom .reset {
@apply bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4;
}
.svg-pan-zoom .zoom-out {
@apply bg-gray-300 hover:bg-gray-400 text-gray-800 font-bold py-2 px-4 rounded-r;
}
You can configure HTML classes used by UI:
const classes = {
zoomIn: "zoom-in",
reset: "reset",
zoomOut: "zoom-out",
buttons: "buttons",
tsWarning: "touchscreen-warning",
tsWarningActive: "active",
};
new SvgPanZoomUi({ element, container, classes });
and message with instructions for the touchscreen:
const message = "Use two fingers to pan and zoom";
new SvgPanZoomUi({ element, container, message });
Pixelation in Safari
Be aware that some CSS will cause pixelation of SVG on zoom (bug in Safari), for example:
will-change: transform;
transform: matrix3d(...);
transition-property: transform;
(it setles after animation, though)
Alternatives
There are a lot of solutions for this task:
- https://github.com/bumbu/svg-pan-zoom
- https://jillix.github.io/svg.pan-zoom.js/
- https://github.com/anvaka/panzoom
- https://www.npmjs.com/package/svg-pan-zoom-container
- https://svgjs.dev/docs/3.0/plugins/svg-panzoom-js/
- https://www.npmjs.com/package/react-svg-pan-zoom
- https://timmywil.com/panzoom/
- https://www.jqueryscript.net/other/SVG-Pan-Zoom-jQuery-SVGPanZoom.html
- https://www.d3indepth.com/zoom-and-pan/
- https://www.npmjs.com/package/react-zoom-pan-pinch