Reputation: 75
So i'm working on developing a map with svg and I wanted to be able to on user input zoom into a predefined area within my svg( a state or country ). I found a tutorial that does exactly this as well as animates it, which is here: https://css-tricks.com/interactive-data-visualization-animating-viewbox/ Also their codepen is here: https://codepen.io/sdras/pen/512230ed732f9b963ad3e50c8d4dcbb8
Now I'm having problems replicating this with my own svg. When I tell it to zoom into a certain area it will zoom into another area. I've tried copying the exact structure of their code with no success. I'm starting to think that the error is within my SVG itself.
HTML:
<svg id="foo" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1440 776">
Then too much code to copy and paste here.
SASS:
html
body
svg
width: 100vw
height: 100vh
JQuery:
var test = document.getElementById("_x32_");
console.log(test);
var s = test.getBBox();
//check the console for the SVGRect object
console.log( s );
//we store the values from the object as our new viewBox string
var newView = "" + s.x + " " + s.y + " " + s.width + " " + s.height;
console.log(newView);
//we then set the new viewBox string as the viewBox attribute on the SVG
var foo = document.getElementById("foo");
console.log(foo);
//foo.setAttribute("viewBox", newView);
The CodePen is here: https://codepen.io/mat148/pen/xqWMXR
Upvotes: 2
Views: 1640
Reputation: 101800
The problem you are having is because the bounding box returned by getBBox()
represents the bounds of the coords of that element before it gets transformed by the transform
attributes on it's ancestor elements.
If we examine the file, we see that the parentage of your element looks like this:
<svg>
<g id="north-america" transform="translate(100.000000, 45.000000)">
<polygon id="_x32_" ...>
So in the case of this particular element, it actually is position at a point 100 to the right and 45 down from the position getBBox()
returns.
If we hack in those offsets, you can see it works.
Obviously, that's not going to be a general solution.
There isn't a very simple solution to this problem, but here are a few approaches you can try:
Alter the SVG to remove all the transforms, by applying them to the paths and polygons. This Stack Overflow question describes some ways to do that with Inkscape.
I believe the RaphaelJS library has a function that can return the transformed bounding box. See Element.getBBox().
Do it yourself by cloning the element, and it's ancestors, to a separate <svg>
then calling getBBox()
on the <svg>
. Ie. create a simplified SVG that looks like the one in the code block ealier in this answer (<svg><g..><polygon>
).
Upvotes: 2