Skip to content

December 8, 2009

65

SVGPan: a Javascript SVG (Viewer) Pan/Zoom/Drag library

Some time ago the need for a browser-compatible vectorial language pushed me to consider the SVG markup language (I won’t say anything about Internet Explorer – it’s just unsupported there). The language itself is great, but, as a beginner, I was so disappointed about the fact that on the Internet I couldn’t find ANY library ready to use for panning and zooming features that I had to write one from scratch.

The SVGPan library features:

  1. Panning (pan à la Google maps) (click on the white background and pan)
  2. Zooming (using the mouse wheel)
  3. Element dragging (click on a drawing element and drag it somewhere else)
  4. Combinations of the above like zooming while dragging

The resulting javascript library is published here, in the hope that someone can find it useful. The library itself is very small and easy to use; and it’s licensed under the BSD license. You can try a demo here

 

No SVG support at all!

 

You can also open the demo in a new page and download the SVGPan library here.

The library itself requires a root group to be identified by the id viewport, which confines the SVGPan library effects, and the import of the javascript code as well. For example, to adapt the tiger drawing, it was necessary to add the following:

<script xlink:href="SVGPan.js"/>
<g id="viewport" transform="translate(200,200)">...

You may also try another SVG example (triple integral, from Wikipedia).

Zeng Xiaohui has provided a patch to support the mouse wheel on Safari/Chrome and fixed the browser scrollbar issue as well. Both patches have been merged into the latest version of SVGPan.

 

The source of this project is now hosted on Google Code, so there you can find the latest version.

 

If you found this code useful please consider donating!

 

Read more from All/News, JavaScript, Web
65 Comments Post a comment
  1. dangerman
    Aug 11 2011

    Andrea, thank you so much for building this! Such an obvious yet sorely lacking bit of functionality.

    One issue: If the SVG is not initially scaled exactly 100%, then zooming does not work properly. If the initial scale is 100% then the opposite happens, and scroll zooming only increases the zoom.

    In my case the SVG is the width of the browser window. I use a fixed viewBox but dynamic 100% width. So my SVG almost never starts at scale=1.0.

    Do you have any idea how to work around this?

    I will keep puttering about, and if I find a solution I’ll post it here.

    Thanks again for this library,
    -dan

  2. Aug 11 2011

    Hello Dan,
    give a look at the latest trunk version in the svn repository at svgpan.googlecode.com: it may fix the issue you’re experiencing! Let me know.

    Regards,

    Andrea

  3. dangerman
    Aug 12 2011

    I checked out your current 1.2.2. It does zoom correctly now when the initial zoom is not 1.0. But there’s a new problem: since you remove the viewBox element from the node, when I resize the page the image gets cropped wrong because the viewBox is missing.

    I had been trying another approach: store the initial CTM as “CTMonload” and then instead of starting all transformations with:
    g.getCTM()

    I’d start them with
    g.getCTM().multiply(CTMonload.inverse()

    that is, start by normalizing to 100%, then applying the transformation. I haven’t gotten it totally working but I think it’s an OK approach. What do you think?

    drop me a line at dan dot moran at the usual gmail and I can give you a link to the page I’m working on. Then you can easily see the problem with removing the viewBox.

  4. dangerman
    Aug 12 2011

    Hi Andrea,

    I got something working for my situation. I have a world map that should take 100% of the browser width, but I have a viewbox=”0 0 1200 600″. The problem I faced is that resizing the browser window resizes the element just fine, but does not resize the element.

    My solution was to add this onresize() handler. When the document is initialized I set initWidth and initHeight to the width and height of the viewbox (though in fact I cheated and hardcoded the viewbox values)

    There’s a minor bug in my solution. When you resize the browser window, any pan/zoom you have done is reset.

    function handleResize(evt){

    var svgDoc = evt.target;
    var g = getRoot(svgDoc);
    /* BUG: on window resize, the scale is reset to 1.0 */
    var scalex = g.parentElement.width.baseVal.value / initWidth;
    var scaley = g.parentElement.height.baseVal.value / initHeight;
    var k = root.createSVGMatrix().scale(scalex).multiply(g.getCTM().inverse());
    setCTM(g, g.getCTM().multiply(k));
    }

    cheers,
    dan

  5. pelucon
    Oct 3 2011

    Hi Andrea,

    this is great, but I can only get it to work when opening the svg by itself. If I load the SVG using the JQuery SVG plugin, I get this error when trying to zoom or pan. (I have created a group with id=”viewport”)

    Uncaught TypeError: Object # has no method ‘createSVGPoint’
    getEventPointSVGPan.js:133
    handleMouseDownSVGPan.js:257
    (anonymous function)8:1
    onmousedown

    Have you tried using your library with Jquery SVG?

    thanks

  6. Maria
    Oct 4 2011

    Hello this is really helpful!
    i am not a programmer but working on a small fashion project.
    i can manage to get the library to work with one svg object.
    but in my project i have 413 different svg objects in the same page!
    the question is can i make each of the objects independability draggable?
    thoguh i don’t need zooming
    give me some hints please :)

  7. catx
    Oct 25 2011

    Hola!

    I’m using graphviz with ‘tooltip’ entries to generate svg with objects like the following, using a xlink:title. Unfortunately, while SVGPan works very nicely without the xlinks, it fails completely with them.

    foo

    foo

  8. Danny Browne
    Nov 28 2011

    pelucon, I was able to just use the basic jQuery $.append to add an embed tag to the DOM and it seems to work perfectly. Would that work for you?

  9. Danny
    Nov 28 2011

    andrea,

    Does the script tag have to be inside the SVG tag? I was hoping to have your library referenced outside the actual SVG because I’ll be dealing with dynamically generated SVG images that I need this functionality on.

    Maybe there’s a clean way to modify the SVG with JS to add the script at the same time I am appending the embed tag to the DOM?

    Thanks for sharing such a great library!

    – Danny

  10. Gary Weinreb
    Dec 5 2011

    Ciao Andrea,

    This is a nice and very useful piece of work…

    I am working on a project for a commercial client and would like to incorporate SVGPan.js into a rather specialized application which has no mouse, but only a very limited input device. We require simple zoom and pan driven by a simple JS function call into your library, rather than the current event handler methodology.

    My question is this: Would you be interested in working with me, for pay, to make these modifications to the SVGPan.js for our specific use?

    Thanks, and best regards,
    Gary

  11. talos
    Jan 13 2012

    I’ve adapted svgpan as a jQuery plugin. This lets you apply the features to arbitrary in-page SVG data.

    https://github.com/talos/jquery-svgpan/
    http://talos.github.com/jquery-svgpan/demo.html

    The main use case is for visualizations from SVG generators like d3:

    http://mbostock.github.com/d3/

    Thanks for putting this together!

  12. Mark
    Jan 19 2012

    How can this be adapted if you have multiple group/viewpoints.

    My SVG will have nested SVGs, some of which are images, we need to be able to manually drag these images individually.

    If I have multiple SVGs in with group/viewpoints only the first one found moves, what I could do with is a way the select the required SVG on mouseDown.

  13. Corey Wirun
    Jan 27 2012

    Hi Andrea,

    Do you know if this will work if the element is contained in an HTML file? Does not look like it, as of yet…

    Regards,
    Corey.

Trackbacks & Pingbacks

  1. Sleepy Lemmata - Raphaël-ZPD: A plugin for the Raphaël vector graphics library enabling zoom, pan and drag functionalities – Sleepy Lemmata
  2. SVGPan 1.2.1 released | cyberz.org

Share your thoughts, post a comment.

(required)
(required)

Note: HTML is allowed. Your email address will never be published.

Subscribe to comments