Reputation: 31
Im trying to figure out how svg viewBox work but the code below breaks all logic.
<svg width="100" height="100" viewBox="0 0 1 20">
<circle cx="10" cy="10" r="10" fill="red"/>
</svg>
In my reality viewBox is for defining the area of svg canvas to show in the viewport. The result of this code should be the left most little piece of circle is centered horizontaly with white space on both sides but chrome nor do firefox follow this logic.Can some one explain how this work? And sorry for my english, i hope you undestand what im trying to say.
Upvotes: 0
Views: 1004
Reputation: 101810
The browsers are rendering your SVG correctly.
The viewBox
just defines the area that should be scaled to fit the viewport. The content is not clipped to the viewBox. If there are elements outside of the viewBox, but still within the viewport, then those will be visible.
In your case, you have asked the browser to center the very left edge of the circle in the viewport. But there is enough room for much of the rest of the circle to be visible.
svg {
background-color: linen;
}
<svg width="100" height="100" viewBox="0 0 1 20">
<circle cx="10" cy="10" r="10" fill="red"/>
<rect width="1" height="20" fill="none" stroke="black" stroke-width="0.3" stroke-dasharray="0.5 0.5"/>
</svg>
Upvotes: 1
Reputation: 123995
The problems here are that most of the circle is outside the viewBox (it's only 1 unit wide and the circle is 20 units wide) and the viewBox aspect ratio is not the same as the aspect ratio of its container.
The default for preserveAspectRatio is to maintain the aspect ratio rather than distorting the shape so we still need to draw a circle rather than an ellipse. Since the drawing area is square the circle will therefore draw into that square area and as the height of the viewBox is 20 we'll have a 20 x 20 area to draw into to draw a circle.
What do we do with the 1 unit viewBox width then? How do we map 0-1 to 20 units? We need to keep the middle value of the viewBox so that's 0.5.
We need to solve these equations then for x and y: (x + y) / 2 = 0.5 (keep the centre the same) and y - x = 20 (keep the width the same as the height to preserve the aspect ratio)
Doing the maths here: x + y = 1 -> y - (1 - y) = 20 -> 2y - 1 = 20 -> y = 10.5 and x = -9.5.
So we're going to display 0 - 20 for height and -9.5 - 10.5 in width which means you'll see roughly (but not quite) half a circle. You actually see slightly more than half the circle.
Upvotes: 1