Skip to content

December 8, 2009

97

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
97 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.

  14. Tim
    Feb 12 2012

    This is wonderful – exactly what’s needed to make SVG useful for data visualisation. Thanks a lot.

  15. Ed
    Feb 15 2012

    Andrea,
    In 1.2.2, I had a problem where SVGPan.js was applying its transform to the <svg> element instead of the <g id=”viewport”> element. Here is the change I made which solved the problem. I sort-of think it’s a good safe thing to add.

    -setupHandlers(root);
    +if (window.addEventListener) { // W3C standard
    + window.addEventListener('load', setupHandlers, false); // NB **not** 'onload'
    +} else if (window.attachEvent) { // Microsoft
    + window.attachEvent('onload', setupHandlers);
    +}

    and

    -function setupHandlers(root){
    +function setupHandlers(){

    since ‘root’ is a global variable already set to document.documentElement earlier.

  16. David
    Feb 21 2012

    Is it possible to use your script with matrix3D for the best performance? I know you can use translate3d in css to use the GPU and accelarate the performance.

    Thank You!

    David

  17. Jonathan Brosseau
    Feb 27 2012

    Hello, We are developing a 2d floor plan viewer using SVG and we struggle implementing multi-touch pan and zoom that work properly… anyone can help at developing this for us as a freelance please let me know.

    We are using webkit-transform.. an exemple of what we are trying to do: http://vps1.alpha-vision.com/svg/vps/dave/vps3/tabletzoompandave.html

    jonathan.brosseau@alpha-vision.com

  18. Mar 5 2012

    Thank you, I’ll give it a try! Anyway feel free to submit bugs/patches on svgpan.google.com. (PS: if you are willing to develop svgpan I can give add you as committer on googlecode).

  19. John
    Mar 7 2012

    Hey Andrea, Great script, thank you. I’m having some problems with it though – see issue 16. I am willing to come up with a fix but really need some help as where to start. I think the translation from my nested SVG elements isn’t being accounted for properly.

  20. Jay Lemmon
    May 15 2012

    It’d be nice if the zoom speed changed based on how far you were zoomed in. That is, an exponential scale. You could do zoom factor = base ^ “scroll wheel clicks from origin” (where you’d probably need to fudge around with base to find a good value).

  21. Achim Abeling
    Aug 24 2012

    Hi Andrea,

    thanks for your work.

    As an extension I would like to have a method which centers a given element.
    My use case is the following:
    - I have a graph (created by graphviz)
    - when clicking on a transition I want the target node to be displayed in the center of the screen

    Perhaps you have a simple solution for this.

    Best regards
    Achim

  22. I and also my buddies ended up analyzing the good tricks on your web
    page and so immediately got an awful feeling I had not
    thanked the web blog owner for those tips. All of the ladies came as a result warmed to study all of them and now
    have very much been taking advantage of them.
    I appreciate you for being indeed considerate as well
    as for going for this sort of remarkable issues most people are really desperate to know about.
    Our own sincere apologies for not expressing gratitude to sooner.

  23. Sep 20 2012

    This looks like it would be great!!! Thank you for your efforts!!!

    We have a complex svg file that has multiple g tags. If I try to use this js in our svg, I get:

    TypeError: matrix is null
    [Break On This Error]

    …matrix.a + “,” + matrix.b + “,” + matrix.c + “,” + matrix.d + “,” + matrix.e + “…

    SVGPan.js (line 145)

    Can you help?

  24. Sep 21 2012

    Can you provide a test case please?

  25. Sep 24 2012

    Very good post. I absolutely appreciate this website.
    Stick with it!

  26. Sep 28 2012

    Here is a pretty small test case:

    http://nick.thepinc.com/view.html

    Thanks!

  27. Sep 30 2012

    Greate post. Keep writing such kind of information on your page.

    Im really impressed by your blog.
    Hey there, You have performed an incredible job.
    I will certainly digg it and individually recommend to my friends.
    I’m sure they’ll be benefited from this site.

  28. Dec 26 2012

    Hello there, There’s no doubt that your web site could possibly be having internet browser compatibility issues. When I take a look at your site in Safari, it looks fine however, when opening in I.E., it’s got some overlapping issues.
    I simply wanted to give you a quick heads up!
    Other than that, great website!

  29. Hello, everything is going sound here and ofcourse every one is sharing information, that’s genuinely fine, keep up writing.

  30. http://www.bearmarketinvestments.com/directory/user_detail.php?u=dewaynedi
    Jan 13 2013

    Real informative and great anatomical structure of articles,
    now that’s user genial (:.

  31. Jan 17 2013

    I rarely comment, but I looked at a few of the remarks on this page SVGPan:
    a Javascript SVG (Viewer) Pan/Zoom/Drag library |
    cyberz.org. I actually do have a few questions for you if it’s allright. Is it just me or does it look like like some of the responses appear as if they are written by brain dead folks? :-P And, if you are posting at additional online sites, I’d
    like to follow you. Could you list of every one of all your social pages
    like your twitter feed, Facebook page or linkedin profile?

  32. Hichem CHTARA
    Mar 12 2013

    excellent work
    I was looking for such thing
    Pan, Zoom, Identify the selected object, …
    Rotate, Edit, this seems to request a big knowladge about javascript

    thanks for sharing !!!

  33. John
    Apr 8 2013

    Hi,

    I’ve found svgPan fantastic, but I’m just wondering if the difficulties with IE8 were ever fixed? I’ve run in to the same issue as Matock i.e.

    Expected identifier, string or number line 98, column 1.

    Any help would be greatly appreciated!

    Thanks in advance,

    John

  34. Apr 16 2013

    I thought this particular script had been the coolest aspect ever.

  35. offiiz
    Apr 19 2013

    By default, SVG image using SVGPan is set to the center of the webpage horizontally and vertically.

    How can I manually set the position of svg image? Which a part of code I can modify to meet my requirement?

    Thanks in advance.

    Anyway, Your library is so cool!

  36. May 2 2013

    Very nice design and wonderful subject matter, nothing else
    we need : D.

  37. Wonderful work! This is the type of info that should be shared across
    the web. Disgrace on the seek engines for not positioning
    this post upper! Come on over and consult with my site
    . Thank you =)

  38. Nick
    Aug 8 2013

    Hello,

    your script is very impressive, thank you. I want to test with an SVG image, do you have a simple 3 step procedure for how to use your program?

  39. Aug 19 2013

    Check the example – it shows how to use it

  40. Dec 5 2013

    Hello sir. Great tutorial. SVGpan works well. While my SVG file is heavy(more size), so it renders slowly. How can i make it to load smoothly.

  41. Dec 6 2013

    Thanks ! I works light faster !!!

  42. Derek
    Dec 11 2013

    Hi Andrea. Great script! Would it be feasible to add functionality so that a double-click, for example, reset the image &view to its original position/zoom level? Would you consider adding such a feature?

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
  3. SVG zoom with mouse wheel inside HTML document | BlogoSfera
  4. SVG zoom with mouse wheel inside HTML document

Share your thoughts, post a comment.

(required)
(required)

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

Subscribe to comments


− 1 = eight