There are many forms of this question on SO but none of them seem to cover this simple case: I have 2 lines in an SVG and they are drawn with different stroke widths. I've tried multiple tricks from the other posts but nothing seems to work. There is something simple here that I'm missing.
Here is the simplest form of this bug I can reproduce:
<!DOCTYPE html>
<html>
<body>
<svg width="120px" height="410px" viewBox="0 0 120 410">
<g id="rooms" stroke-width="8" stroke="#979797">
<path d="M0,0 L40,0"></path>
<path d="M0,20 L40,20"></path>
</g>
</svg>
</body>
</html>
And here is the drawing result:
I've also created a fiddle, trying to use the other SO articles suggestions, with no effect. I've also tested this in Safari, Chrome, and Firefox and all have the same result.
I'm a little stunned that such a simple thing has this type of drawing bug. I must be missing something very obvious. In the fiddle I also try using LINE instead of PATH and that DOES work properly. This appears to be related to paths.
OK, this was indeed a noob mistake. It wasn't clear that the width of a stoke is centered on the line. All paths drawn along the edge of my viewBox were effectively clipped.
TL;DR: Don't draw from 0,0
Related
I know there are a lots of posts related to this, I had checked all of them and I was not able to get a proper solution for my problem that's why I post this question.
I have a SVG like this:
As you can see that this SVG has no spaces around left and top, but it has some spaces around right and bottom. How can I remove the spaces which at bottom and right side of it?
SVG's source code: stackoverflow's body can have only up-to 30000 characters only but the SVG's source code has more characters than the limitation. Due to reason I had to upload the code at this Gist. I am really sorry for the inconvenience :(
To see the borders of the SVG canvas I added to the header of the SVG file red border style
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 768" version="1.1"
style="border:1px solid red;">
Your image is shifted left and up so there are empty spaces on the right and bottom
jsfiddle
The image shift is performed by the command:
<g id="girl" transform="translate(-35.000000, -89.000000)">
Remove this command or set the coordinates to zero
<g id="girl" transform="translate(0, 0)">
jsfiddle
As a result, the empty spaces will disappear and the image will occupy the entire SVG canvas.
I'm trying to have a SVG path scale to fit the entire container element, without stretching or being trimmed. The SVG is the one below. As you can see, it's a simple border.
<svg preserveAspectRatio="none" viewBox="0 0 370 80" height="100%" width="100%">
<path vector-effect="non-scaling-stroke" d="M359,70C359,70,300,70,185,70C84,70,9,70,9,70C9,70,9,60,9,40C9,24,9,10,9,10C9,10,84,10,185,10C300,10,359,10,359,10C359,10,359,24,359,40C359,60,359,70,359,70C359,70,359,70,359,70"/>
</svg>
Then I have an element that could have different sizes, because it's responsive and because I use it in various cases where width or height can be different. I can't succeed in having the SVG that expands its path by always staying inside the viewport, but scaling without preserving aspect ratio. It doesn't seem a difficult logical thing to do, but I tried various options without success.
EDIT
I was able to scale this SVG, by setting whatever dimensions I wanted. Why does the first not work, but this works instead?
<svg preserveAspectRatio="none" viewBox="0 0 404 77" height="100%" width="100%">
<path vector-effect="non-scaling-stroke" d="m0,0l404,0l0,77l-404,0l0,-77z"/>
</svg>
The short answer is no. What you want to do (as I understand it) is not possible. In SVG you can scale to fit the container (using constant aspect ratio), or you can stretch (ignoring aspect ratio).
There is no way currently to keep some parts of the SVG static and stretch other parts. Unless, of course, you use Javascript to manipulate the contents of the SVG.
What you may want to do is consider using an SVG as the source image for a CSS border-image (see http://www.w3.org/TR/css3-background/#border-images). Perhaps that is the sort of thing you were after?
This is more of a bezier question than an SVG question, but here goes...
given the following code:
<svg xmlns="http://www.w3.org/2000/svg" baseProfile="full" viewBox="0 0 400 400" baseProfile="full">
<path d="M0,0 C20,400 30,200 50,100" fill="#FF0000" stroke="#000000"/>
</svg>
Using [path].getBBox() returns me a height of 400, since the 1st control point of the curve is at 400 y, and this makes sense(ish).
But what I really need is the actual height of the object as rendered, not the box that contains all points used in its drawing.
I'm assuming I'm just going to have to figure it out myself? And if that's the case, does anybody have any suggestions for where to go to find such mathy things? I did some googling, but I'm not really coming up with anything (it's very possible I'm not phrasing the question correctly, some help in that regard would be super nice as well).
You are doing it right, it's a WebKit bug. If you try getBBox on Firefox or even Internet Explorer, it's fine.
If you need a workaround, give a look at the implementation done for SVG-edit.
I am viewing the following svg http://pastebin.com/pNdNEQ6z in my Firefox and chome.
Can someone tell me why the two graphs are somewhere in der middle of y an not starting at the top? If you change the viewbox to "0 200 650 800" everything is fine. why 200? I have played with preserveAspectRatio="xMidYMin" but this is not doing anything.
At the end of the day I want to display both charts completely visible starting at the top? And I would like to understand why it is not doing so right now :-)
Your problem is that you had a typo on your first embedded <svg> element (you had hight="400" instead of height="400") and were not using a …YMin alignment on the outer.
Fixed, it looks like this:
<svg … preserveAspectRatio="xMidYMin">
<svg … height="400">
Demo: http://jsfiddle.net/WAVZj/
Consider this simple SVG file:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:x="http://www.w3.org/1999/xlink"
viewBox="0 0 353 150">
<defs>
<clipPath id="walk0"><rect width="44" height="70" /></clipPath>
<image id="img" x:href="http://phrogz.net/tmp/walking-girl2.png"
width="353" height="70" />
</defs>
<use x:href="#img" clip-path="url(#walk0)" />
<use x:href="#img" y="80" clip-path="url(#walk0)" />
</svg>
The intent is to have two copies of the spritesheet clipped to the same region, with the second copy 80 units lower down. This works as intended in Firefox (the clipping path is applied before the y offset). In Chrome and Safari, however, the second image is not shown. (The clipping path is applied using global SVG unit space, and hence shows an empty area of the image.)
1) Which one of these browsers is correct?, or
2) What is the simplest, standards-based way to achieve this goal?
I can work around the problem by using wrapping <g> elements with transforms; this works in both Firefox and Chrome. But I'm hoping that there's a simpler way to achieve the same results in a correct and cross-browser manner.
FWIW, I also tried setting clipPathUnits="objectBoundingBox" on the clipPath, but this always produced an unclipped image. This was true even when I wrapped the <image> in a <symbol> with an explicit viewBox, height and width and referenced that with the <use> instead of the <image>. Either I don't understand how objectBoundingBox is supposed to work, or support for it is currently broken. It is certainly possible that the answer is the former instead of the latter. ;)
The easiest, standards-compliant way to differentiate between these is to use the SVG test suite provided by W3.org. This suite provides tests for use structs that you can play with to determine compliance, among many others.
The problem is how your y value is being parsed, which is causing your figure to translate out of the second frame, but only in some browsers. This is the correct, cross-browser way to specify the desired translation:
<use x:href="#img" clip-path="url(#walk0)"transform="translate(0,80)"/>
I would assume the dubious parsing with respect to the current clipping pane is a regression.