SVG Coordinates, Viewport, viewBox

, , …,
Want to master JavaScript in a month? Commit. Buy Xah JavaScript Tutorial. You also get Xah HTML Tutorial and Xah CSS Tutorial.

This page is a basic tutorial on SVG “viewBox” attribute. If you are new to SVG, see SVG Tutorial: Basic Examples.

viewport

Here's a circle.

Here's the code:

<svg width="100" height="100">
<circle cx="50" cy="50" r="50"
style="stroke:green; fill:none" />
</svg>

Note the values of the “width” & “height” attributes.

the width & height makes up the area called viewport.

The top left corner of the viewport has coordinate {0,0}. That is, x = 0 and y = 0. this point is called the origin.

Changing the width or height does not change the coordinate.

<svg width="200" height="100">
<circle cx="50" cy="50" r="50"
style="stroke:green; fill:none" />
</svg>
<svg width="70" height="100">
<circle cx="50" cy="50" r="50"
style="stroke:green; fill:none" />
</svg>

viewBox Attribute

You can use the “viewBox” attribute to control the coordinate origin and the coordinate's x range and y range.

here's the syntax of the viewBox:

<svg width="…" height="…" viewBox="min-x min-y width height" >

Any drawing outside of the {width, height} will not be shown.

Here's some examples.

Shifting Coordinates

Here, we shift the coordinate, so the drawing area's top left corner is {30,0}.

Here's a circle centered on {30,0} with radius 20.

<svg width="100" height="100" viewBox="30 0 100 100">
<circle cx="30" cy="0" r="20" style="stroke:green; fill:blue" />
</svg>

Change Visible Range

Here, we set the viewBox's x & y ranges to be both 50.

<svg width="100" height="100" viewBox="0 0 50 50">
<circle cx="0" cy="0" r="50"
style="stroke:green; fill:none" />
</svg>

Your drawing (the viewBox) will always be scaled uniformly to fit in the viewport. (which may leave empty spaces) And the image will be centered. Aspect ratio is preserved by default.

here's the tech detail. Suppose, viewport width and height is {pX,pY} and viewBox width and height is {bX, bY}. Now, there's 2 ratios: pX/bX and pY/bY. Whichever is smaller will be the scaling factor.

Controlling viewport/viewBox Mapping: “preserveAspectRatio” attribute

The “preserveAspectRatio” attribute can be used to control the exact scaling and position of viewBox and viewport.

first, observe that when viewport and viewBox have different width & height, there are these cases:

when the viewBox is scaled uniformly, there's also alignment issue. Namely, allign to {top, middle, bottom} in x-dimension, and same for y-dimension.

SVG provides a very convenient attribute “preserveAspectRatio”. You just tell it which of the above case you want, and you don't have to do any of the math.

here's the syntax:

preserveAspectRatio="none"

the above means don't preserve aspect ratio. Scale each dimention to fit.

to preserve aspect ratio, use this:

preserveAspectRatio="alignment spec meet or slice"

The possible values for alignment spec is one of:

the meet or slice is either meet or slice.

Nested SVG

You can nest a svg inside a svg. This is useful when you want to have a area for graph and another area for caption, legends, etc.

For example, suppose you want to plot a graph y=x^2. The range you want to plot is {x, 0, 10} and {y, 0, 10}. So, you can create a view box with height & width of 10. But, you also need a area for the graph's caption. Instead of transforming all your coordinates, you can have a nested svg tag inside the main svg viewbox, and this one's viewbox will use the coordinate for your plot.

The syntax for the nested svg is just 2 extra attribute, x & y: <svg x="…" y="…">. The x & y specifies where your inner svg is positioned.

Here's a example:

<svg width="100" height="100">
  <svg x="20" y="20" width="80" height="80" viewBox="0 0 100 100">
    <rect x="0" y="0" width="100" height="100" style="fill:green; stroke:blue; stroke-width:5" />
  </svg>
</svg>

The svg view box is same as view port, with side length of 100. It has a inner svg, with side length of 80, with origin at {20,20}. The inner svg has a viewport with side length of 100. (so, you don't have to rescale your points.) It draws a square of length 100.

blog comments powered by Disqus