Professional Documents
Culture Documents
How To Perfectly Fit An SVG's ViewBox To Its Contents Using JavaScript - DEV Community
How To Perfectly Fit An SVG's ViewBox To Its Contents Using JavaScript - DEV Community
Using the SVG tag on websites is handy, but its interface can be different than we're used
to. In this post, we're going to see how to fit the viewport of an SVG to its contents every
time.
The Problem
In some cases, we might have an SVG with some arbitrary shapes or paths in it. Those
shapes and paths may have specified dimentsions that don't always fit your viewport.
4 4 4
Let's consider the following SVG. We have two paths that I have taken from a map of the
United States. One path is for the state of Maryland and the other is for the state of New
York.
But if we were to fire up our web browser and navigate to this page, we wouldn't see a
thing. Why is that? Well, it's because these paths were taken from a full map of the U.S., so
the origin (0, 0) point of the coordinate system being used is at the top-left of the entire
country—next to Alaska.
This is no good as want our SVG to fit our two states perfectly.
Our Options
4 4 4
We have a couple reasonable options:
1. Transform each path such that it fits our current SVG view
2. Change our SVG "viewBox" to fit our paths
I personally like the second option and will go through that one in this post!
We can see that our SVG is 100x100, but our shapes actually only start at about x = 40 , y
= 30 and end somewhew around x = 80 , y = 90 . What we'd love is for our SVG to zoom
in on that area, so our view looks something like this:
4 4 4
How can we do this? It turns out the svg HTML element has a handy zoomBox attribute
that lets us pass the desired origin's x and y values along with the desired width and
height .
4 4 4
We can see that our origin is at x=40, y=30 and then we have to do a little math for our
width and height:
And this works! Note that, by default, the SVG will center the objects in its viewBox rather
than distorting them.
We use document.querySelector('svg') to grab the only SVG on our page (but make sure
to use an ID or class if you need a different selector!). Next, I use [...svg.children] to (a)
get all of the child elements of our svg and (b) use the spread operator ( ... ) to convert
the HTMLCollection to an array of elements. Have an array enables me to use the reduce
method, which takes a callback function and an initial accumulator (an empty object {} ).
Within the reduce callback, I use the getBBox() method on each element to get the x, y,
width , and height . Using the aformentioned logic, we conditionally overwrite the xMin ,
xMax , yMin , and yMax , properties on our accumulator.
Our one final step is to set he viewBox attribute of the parent svg . Remember, the viewBox
is set to x y width height , so we have to convert our xMax and yMax to width and height ,
respectively!
We can do this with the math we discussed in our simplified example:
svg.setAttribute('viewBox', viewbox);
And we can see it in action with our state SVGs. In fact, we touted the flexibility of this
solution, so it better be able to accommodate an additional state! Let's add North
Carolina for good measure.
4 4 4
CodeSandbox https://2nxsg.csb.app/
friendly-noyce-2nxsg
nas5w
309 0 1
Edit Sandbox
Files
.codesandbox
src
Open Sandbox
index.js
styles.css
Console 0 Problems 0
index html
Conclusion
Thanks for playing with shapes, states, and even a little math with me today. Hopefully
you learned something new today and how have a handy utility to fit items in your SVGs.
Discussion Subscribe
WORK
Software Engineer at USDS
LOCATION
Washington, DC
JOINED
Feb 8, 2019
Future You Will Never Think Current You Was Too Old to Learn Software Engineering
#programming #webdev #beginners #career
Build a useLocalStorage React Hook Package (Contribute to Open Source with Me)
#react #javascript #typescript #webdev
4 4 4