svg-pan-zoom

repository·master·Indexed 24 days ago

https://github.com/bumbu/svg-pan-zoom

A lightweight JavaScript library (v3.6.2) for panning and zooming SVG images via mouse, touch, and programmatic control. It supports inline SVGs as well as those embedded via object or embed tags, providing a fluent API for zooming, panning, and fitting the viewport. Features include customizable zoom scales, event callbacks for intercepting or reacting to changes, and optional on-screen control icons.

Tokens
3.3K
Snippets
7
Records
14
Agent score
84%

What's inside svg-pan-zoom

  1. Use a custom viewport layer

    master

    By default, the library uses the top-level <g> element as the viewport. To pan/zoom only a specific layer, assign the class svg-pan-zoom_viewport to that SVGGElement.

    Important: Do not set any transform attributes directly on the element with the svg-pan-zoom_viewport class. If you need a transform, wrap it in a nested group:

    <g class="svg-pan-zoom_viewport">
      <g transform="matrix(1,0,0,1,0,0);"></g>
    </g>

    You can also specify the viewport via the viewportSelector option in the configuration.

    svgPanZoom('#demo-tiger', {
      viewportSelector: '.svg-pan-zoom_viewport'
    });
  2. Handle remote or dynamically loaded SVGs

    master

    If you are using <embed> or <object> elements to load remote SVGs, or if you render the SVG after the page has loaded, you must wait for the SVG to be loaded before calling svgPanZoom. You can do this by listening to the load event on the element.

    <embed type="image/svg+xml" src="/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>
  3. Initialize svg-pan-zoom

    master

    To use the library, reference the svg-pan-zoom.js file in your HTML. You can initialize pan and zoom behavior by calling the svgPanZoom function with either a CSS selector of an SVG element or the DOM element itself.

    var panZoomTiger = svgPanZoom('#demo-tiger');
    // or
    var svgElement = document.querySelector('#demo-tiger')
    var panZoomTiger = svgPanZoom(svgElement)
  4. Implement custom events (e.g., Hammer.js)

    master

    You can add custom event support (like pinch or double tap) using the customEventsHandler option. This requires providing haltEventListeners (to prevent conflicts with default touch events), an init function, and a destroy function.

    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);
  5. Configure svg-pan-zoom options

    master

    You can override default behaviors by passing an options object as the second argument to svgPanZoom.

    Available Options:

    • viewportSelector: querySelector string or SVGElement.
    • panEnabled: boolean (default: true).
    • controlIconsEnabled: boolean (default: false).
    • zoomEnabled: boolean (default: true).
    • dblClickZoomEnabled: boolean (default: true).
    • mouseWheelZoomEnabled: boolean (default: true).
    • preventMouseEventsDefault: boolean (default: true).
    • zoomScaleSensitivity: scalar (default: 0.2).
    • minZoom: scalar (default: 0.5).
    • maxZoom: scalar (default: 10).
    • fit: boolean (default: true).
    • contain: boolean (default: false). Note: fit takes precedence over contain.
    • center: boolean (default: true).
    • refreshRate: number or 'auto'.
    • beforeZoom: callback function (oldZoom, newZoom) => void. Returning false halts zooming.
    • onZoom: callback function (newZoom) => void.
    • beforePan: callback function (oldPan, newPan) => void. oldPan and newPan are objects with {x, y}. Returning false or {x: true, y: true} halts panning. Returning {x: 10, y: 20} alters the current pan step.
    • onPan: callback function (newPan) => void.
    • onUpdatedCTM: callback function called asynchronously after CTM updates.
    • customEventsHandler: object with init and destroy functions.
    • eventsListenerElement: SVGElement or null.
    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
    });
  6. Use the standalone version of svg-pan-zoom in the browser

    master
    The standalone version of the library is designed for direct browser usage. When included via a <script> tag, it attaches the svgPanZoom object to the global window object, allowing you to access the library's API directly in your client-side code.
  7. Troubleshoot common issues

    master

    SVG height is broken

    Because the library removes the viewBox attribute, the SVG height might default to a small value (e.g., 150px). Fix: Explicitly set a height on the SVG or its object/embed container.

    Errors when SVG is hidden

    The library does not support working with SVGs that are hidden (e.g., display: none), as browsers may detach child documents from the DOM when they are hidden.

    Performance issues

    • Initialization: If initialization is slow, wrap all child elements in a single <g> element beforehand to prevent the library from having to move them.
    • Panning/Zooming: Slow performance is usually caused by very large SVG files that the browser cannot render quickly enough.
  8. Update viewport bounding box

    master

    If you modify the contents of the SVG (the viewport) such that the bounding box of all elements changes, you must call updateBBox() so that fit() and other calculations work correctly.

    var panZoomTiger = svgPanZoom('#demo-tiger');
    panZoomTiger.fit();
    
    // Update SVG rectangle width
    document.getElementById('demo-tiger').querySelector('rect').setAttribute('width', 200)
    
    // fit does not work right anymore as viewport bounding box changed
    panZoomTiger.fit();
    
    panZoomTiger.updateBBox(); // Update viewport bounding box
    panZoomTiger.fit(); // fit works as expected
  9. Programmatically pan and zoom

    master

    The svgPanZoom instance provides several methods for programmatic control:

    Panning:

    • pan({x, y}): Pan to a specific rendered point.
    • panBy({x, y}): Pan by a specific number of rendered pixels.

    Zooming:

    • zoom(scale): Set a specific zoom scale.
    • zoomBy(factor): Zoom by a multiplier (e.g., 1.3 for 130%).
    • zoomAtPoint(scale, {x, y}): Set zoom scale at a specific point.
    • zoomAtPointBy(factor, {x, y}): Zoom by a factor at a specific point.
    • zoomIn() / zoomOut(): Incremental zoom.
    • resetZoom(): Reset to initial scale.

    Other Controls:

    • enablePan() / disablePan()
    • enableZoom() / disableZoom()
    • fit(): Fit the SVG to the container.
    • center(): Center the SVG.
    • reset(): Reset both pan and zoom.
    // Get instance
    var panZoomTiger = svgPanZoom('#demo-tiger');
    
    // Pan to rendered point x = 50, y = 50
    panZoomTiger.pan({x: 50, y: 50})
    
    // Pan by x = 50, y = 50 of rendered pixels
    panZoomTiger.panBy({x: 50, y: 50})
    
    // Set zoom level to 2
    panZoomTiger.zoom(2)
    
    // Zoom by 130%
    panZoomTiger.zoomBy(1.3)
    
    // Set zoom level to 2 at point
    panZoomTiger.zoomAtPoint(2, {x: 50, y: 50})
    
    // Zoom by 130% at given point
    panZoomTiger.zoomAtPointBy(1.3, {x: 50, y: 50})
    
    // Incremental zoom
    panZoomTiger.zoomIn()
    panZoomTiger.zoomOut()
    panZoomTiger.resetZoom()
  10. Get SVG dimensions and zoom state

    master

    Call getSizes() to retrieve an object containing the current state of the SVG:

    • width: Cached SVG width.
    • height: Cached SVG height.
    • realZoom: The a and d attributes of the transform matrix applied over the viewport.
    • viewBox: An object containing width, height, x, and y of the viewport bounding box.
  11. Enable on-screen zoom control icons

    master

    You can add on-screen zoom controls (Zoom In, Reset, and Zoom Out) to your svg-pan-zoom instance by calling the enable method from the control icons module. This method injects SVG elements into your SVG container, including a <style> block for styling the controls. The controls are positioned relative to the SVG's width and height.

    Note that the enable method attaches the created control group to the instance.controlIcons property, allowing you to reference them later.