SVG viewBox with negative coordinates - html

I want to create re-usable shapes that will automatically scale to fit the size of the given viewPort when used.
My approach is to enclose the shape in a 'symbol' element, and give it a viewBox with the same size as the shape itself.
This seems to work with a circle and a rectangle, but I am having trouble with a diamond shape, drawn using a path.
I have found a solution by creating a viewBox of (-1, -1, width+2, height+2), but I would like to know if this is officially supported, or if there is a better solution.
In the following example, the first shape is drawn directly, the second shape is derived from a 'use' element. If the viewBox starts with '0, 0', the left and top pixels are missing.
<html>
<svg width="200" height="200"
style="margin:20px; border: 1px solid gray">
<path d="M 80 0 L 0 80 L 80 160 L 160 80 Z"
stroke="black" stroke-width="2"
stroke-linejoin="round" fill="transparent"
transform="translate(20, 20)"/>
</svg>
<svg style="display:none">
<symbol id="gw" viewBox="-1 -1 162 162">
<path d="M 80 0 L 0 80 L 80 160 L 160 80 Z"
stroke="black" stroke-width="2"
stroke-linejoin="round" fill="transparent"/>
</symbol>
</svg>
<svg width="200" height="200"
style="margin:20px; border: 1px solid gray">
<use href="#gw" width="160" height="160" transform="translate(20, 20)"/>
</svg>
</html>

This took me a while to debug - my issue was that I specified the viewbox as viewbox and not viewBox, so the viewBox wasn't even being applied. Check your capitalization!

It seems that negative coords for the origin are supported: https://www.w3.org/TR/SVG/coords.html implies that there is no restriction on the first two parts of a 'viewbox'. I've seen elsewhere that people sometimes use negative coords on a viewbox.

Related

Does SVG path element support a lifting of the pen?

In SVG there are different commands used such as move pen, draw line, draw curve and so on like so:
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
<path d="M10 10 H 90 V 90 H 10 L 10 10"/>
</svg>
Is there a command that lifts the pen and then sets the pen down again? As an example, is there a single value of SVG path data that would draw parallel lines that do not intersect inside a single path element?
More info on SVG on MDN.
Thanks to #RobertLongson for pointing this out.
I can use move more than once. In this case it is in the middle of the statement.
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
<path d="M10 10 H 90 M 10 90 H 90" stroke="red"
stroke-width="3" fill="none"/>
</svg>

Create a simple wave with SVG issue

I am trying to create a simple wave with SVG to put on my website. This is what I've come up with so far:
<svg height="100" width="500">
<path d="M 0 50
Q 125 0, 250 50, 375 100, 500 50
L 500 100
L 0 100
L 0 50
Z" stroke="blue" stroke-width="1" fill="red" />
</svg>
https://jsfiddle.net/a5q41t26/
The problem is that I can't align the bottom of the path with the bottom of the lower wave to avoid the gap.
Any help would be appreciated.
The first coordinate pair, of the two pairs in a Q path command, is a control point. The curve does not pass through the control point.
Have a look at the section on Quadratic bezier curves in Wikipedia.

Change svg height

I have a svg in my page which forces its container's height. It moves other elements... Is it possible to change svg's height? Now svg element is a square and a rectangle will be better because height is too big.
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 60 60" enable-background="new 0 0 30 30" xml:space="preserve" width="50%" height="11%">
<path fill="none" stroke="white" stroke-miterlimit="10" d="M19.7,7.6C15.3,4,9.1,4.1,5.3,7.7c-3.2,3-4,8-2.1,12
c2.1,4.4,7.1,6.6,11.3,5.7c2.6-0.5,4.3-2.1,5.1-2.9"/>
<line fill="none" stroke="white" stroke-width="1.1572" stroke-miterlimit="10" x1="19.3" y1="7.3" x2="10.8" y2="15.5"/>
<line fill="none" stroke="white" stroke-width="1.3426" stroke-miterlimit="10" x1="10.9" y1="14.8" x2="19.7" y2="23.2"/>
<line fill="none" stroke="none" stroke-width="1.1322" stroke-miterlimit="10" x1="14.7" y1="15.4" x2="23.5" y2="7.1"/>
<line fill="none" stroke="none" stroke-width="0.9577" stroke-miterlimit="10" x1="14.9" y1="14.9" x2="22.7" y2="22.6"/>
<path fill="none" stroke="none" stroke-width="1.0915" stroke-miterlimit="10" d="M22.9,7.2c0.3,0.1,0.6,0.4,1,0.7
c1.8,1.4,3.9,4.2,3.4,7.9c-0.4,3-2.4,5.6-5.2,6.7"/>
<text x="20" y="18" fill="White" class="textsvg" font-size="10">MENU</text>
</svg>
[Jsfiddle][1]
Thanks!
Look on this updated jsFiddle: https://jsfiddle.net/qqzox761/1/
I removed width and height from your svg and changed viewBox a little bit.
Now with this code of svg you can set size in css.
Change the viewbox attribute, here:
<svg ... viewBox="0 0 60 60" ...
It means it is a square SVG that starts at 0, 0 and have a size of 60 on each side. Changing this will only affect the aspect ratio of SVG view, you can assign its width more accurately in pixels or percent using CSS.
As noted by mwl, you need to delete the width and height from <svg>. The program you used to create the graphic adds data to viewbox automatically so while mwl modified it, it looks like you had extra white space when you saved the file. I also recreated your fiddle here but without the white space. The important thing to remember about SVG is that it's all about scaling which means, in part, that preserving the aspect ratio is more important than pixel dimensions. This is a great article by Amelia Bellany-Royds on CSS-Tricks if you want more information.

Adjacent lines inside svg path with stroke-width

I have a svg with multiple lines inside a path.
<path stroke-width="13" stroke="black" fill="orange" d="M 100 100 L 300 100 Z L200 300 z"/>
Because of the stroke-width the lines intersect
Is there any way of making the path continuous without altering the "d" attribute?
Edit:
I am interested in how you can control the joins of multiple objects inside the same path while having a stroke-width defined.
If I would change the "d" attribute and remove the middle Z so that the lines form a triangle the stroke problem would disappear
That's one hell of an overhang for two lines that meet at a point. (Are you using Firefox by any chance? I saw something very similar recently.)
If you want a neat join between two disjoint line segments, your best bet would be to draw them with rounded end caps by adding stroke-linejoin="round" and stroke-linecap="round" to the path element.
And if my suspicion is correct, you can fix the overhang problem by changing fill="orange" to fill="none". Try this:
<svg viewBox="50 50 400 400" width="350" height="350">
<path stroke-width="13"
stroke="black"
fill="none"
stroke-linejoin="round"
stroke-linecap="round"
d="M 100 100 L 300 100 Z L200 300 z"
/>
</svg>

SVG path not observing aspect ratio

I'm having trouble getting the SVG path to scale to its container:
<svg xmlns="http://www.w3.org/2000/svg"
preserveAspectRatio="xMidYMid"
viewBox="0 0 16 16"
width="16"
height="16">
<path stroke="#000" fill="none" d="M209,15a195,195 0 1,0 2,0zm1,0v390m195-195H15M59,90a260,260 0 0,0 302,0 m0,240 a260,260 0 0,0-302,0M195,20a250,250 0 0,0 0,382 m30,0 a250,250 0 0,0 0-382"></path>
</svg>
Demo: http://jsfiddle.net/FeTv2/1/ - As you can see the path is way too big, and seems to have a top and left offset.
Looks the same in Chrome and Firefox.
The viewBox of you SVG is way too small to fit the path you're using. The viewBox represents the part of your SVG, that should be shown. The width and height the represent the dimension of the box, in which the content is shown.
Try a viewBox size, that really fits your path like this (may need further adjustments):
<svg height="16" width="16"
viewBox="0 0 450 450"
preserveAspectRatio="xMidYMid"
xmlns="http://www.w3.org/2000/svg">
<path d="M209,15a195,195 0 1,0 2,0zm1,0v390m195-195H15M59,90a260,260 0 0,0 302,0 m0,240 a260,260 0 0,0-302,0M195,20a250,250 0 0,0 0,382 m30,0 a250,250 0 0,0 0-382" fill="none" stroke="#000"/>
</svg>
Additionally, you may (or may not) want to adjust the size of the <svg> element.
Example Fiddle (big <svg>)
Example Fiddle (16x16 <svg>)