I'm trying to build svg-line (or path - doesn't matter) with repeating markers along it's entire length. What is the best way to implement it?
There is a description of marker-pattern property on w3. It looks perfect but for some reason I can't get the correct result in my code.
Furthermore, I don't see any markers, replicating the w3 example:
https://jsfiddle.net/pLaukq8p/
<svg xmlns="http://www.w3.org/2000/svg" width="600" height="200">
<marker id="DoubleDash" markerWidth="8" markerHeight="12" refX="0" refY="0"
viewBox="-4 -6 8 12" markerUnits="userSpaceOnUse" orient="auto">
<rect x="-3" y="-5" width="2" height="10"/>
<rect x="1" y="-5" width="2" height="10"/>
</marker>
<marker id="SingleDash" markerWidth="4" markerHeight="12" refX="0" refY="0"
viewBox="-2 -6 4 12" markerUnits="userSpaceOnUse" orient="auto">
<rect x="-1" y="-5" width="2" height="10"/>
</marker>
<path d="M 50,100 S 100,132 150,86 200,173 250,76 300,81
350,136 400,87 450,166 500,87 550,96"
stroke="deeppink" stroke-width="2" fill="none"
marker-pattern="40 url(#DoubleDash) 40 url(#SingleDash)"/>
</svg>
Related
when loading an SVG file (designed in Inkscape) with the Fabric.js function loadSVGFromURL(), the including text gets rendered larger than in Inkscape.
here you can see a screenshot from Inkscape:
SVG in Inkscape
This is how it looks like in Fabric.js:
SVG in Fabric
However, I also recognized, that the SVG looks slightly different in Chrome (different than Inkscape and different than Fabric.js):
SVG in Chrome
this is what the SVG looks like:
<svg xmlns="http://www.w3.org/2000/svg" width="30" height="45" id="svg4136" version="1.1">
<defs id="defs4138">
<marker orient="auto" refY="0" refX="0" id="Arrow1Mend" style="overflow:visible">
<path id="path4750" d="m0 0 5-5-17.5 5L5 5Z" style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1" transform="matrix(-.4 0 0 -.4 -4 0)"/>
</marker>
<marker orient="auto" refY="0" refX="0" id="Arrow2Mend" style="overflow:visible">
<path id="path4768" style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1" d="M8.719 4.034-2.207.016 8.719-4.002c-1.746 2.372-1.736 5.618 0 8.036z" transform="scale(-.6)"/>
</marker>
<marker orient="auto" refY="0" refX="0" id="Arrow1Send" style="overflow:visible">
<path id="path4756" d="m0 0 5-5-17.5 5L5 5Z" style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1" transform="matrix(-.2 0 0 -.2 -1.2 0)"/>
</marker>
<marker orient="auto" refY="0" refX="0" id="Arrow1Lstart" style="overflow:visible">
<path id="path4741" d="m0 0 5-5-17.5 5L5 5Z" style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1" transform="matrix(.8 0 0 .8 10 0)"/>
</marker>
<marker orient="auto" refY="0" refX="0" id="Arrow1Lend" style="overflow:visible">
<path id="path4744" d="m0 0 5-5-17.5 5L5 5Z" style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1" transform="matrix(-.8 0 0 -.8 -10 0)"/>
</marker>
</defs>
<g id="layer1">
<path style="fill:#cecece;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.6;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" id="rect4197" d="M0 0h30v45H0z"/>
<text id="text4996-5" y="51.248" x="-35.24" style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:0%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;white-space:pre;inline-size:60.4796;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" xml:space="preserve" transform="rotate(-90 -22.186 10.427)"><tspan x="-35.24" y="51.248"><tspan style="font-size:10px;line-height:1.25">###LABEL</tspan></tspan></text>
</g>
Does anybody know what causes this behavior?
Thanks and all the best,
Kevin
According to https://developer.mozilla.org/en-US/docs/Web/SVG/Element/circle, the pathLength attribute is supposed to define the "total length for the circle's circumference", however, when I use stroke-dasharray, it doesn't seem to line up?
<svg width="100" height="100" viewBox="0 0 1 1">
<circle
cx="0.5"
cy="0.5"
stroke-width="0.5"
r="0.25"
pathLength="360"
stroke-dasharray="180 360"
stroke-dashoffset="0"
stroke="black"
fill="none"
/>
</svg>
According to https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/pathLength as well, this should be half-filled, thus a semi-circle, however it's slightly less than a semi-circle. If I have stroke-dasharray set to 360 360 instead, it doesn't fully close when, if I understand how the pathLength attribute is supposed to work, it should.
Am I misunderstanding pathLength or stroke-dasharray?
Edit: it seems to work differently across browsers...?
Chromium:
Firefox:
Safari:
Edit 2:
When I get their total lengths, it's different across browsers! Is this intended? Is it possible to solve this issue?
As #enxaneta commented. The smaller the viewBox, the bigger the problem is. In this example it is only the last one (viewBox="0 0 100 100") that looks OK in Chrome.
<svg xmlns="http//www.w3.org/2000/svg" width="130" viewBox="0 0 1 1">
<path d="M0 .5 L1 .5" stroke-width=".01" stroke="gray"/>
<circle cx=".5" cy=".5" r=".4" stroke="black" stroke-width=".2" fill="none" stroke-dasharray="180 360" pathLength="360" />
</svg>
<svg xmlns="http//www.w3.org/2000/svg" width="130" viewBox="0 0 10 10">
<path d="M0 5 L10 5" stroke-width=".1" stroke="gray"/>
<circle cx="5" cy="5" r="4" stroke="black" stroke-width="2" fill="none" stroke-dasharray="180 360" pathLength="360" />
</svg>
<svg xmlns="http//www.w3.org/2000/svg" width="130" viewBox="0 0 50 50">
<path d="M0 25 L50 25" stroke-width=".5" stroke="gray"/>
<circle cx="25" cy="25" r="20" stroke="black" stroke-width="10" fill="none" stroke-dasharray="180 360" pathLength="360" />
</svg>
<svg xmlns="http//www.w3.org/2000/svg" width="130" viewBox="0 0 100 100">
<path d="M0 50 L100 50" stroke-width="1" stroke="gray"/>
<circle cx="50" cy="50" r="40" stroke="black" stroke-width="20" fill="none" stroke-dasharray="180 360" pathLength="360" />
</svg>
I'm drawing an SVG line with a "marker-end" to make it an arrow. It draws the arrowhead extending beyond the end of the line, making the whole arrow longer, but I would like the whole arrow to be the same length as the original line. That is, the tip of the arrowhead should be at the endpoint of the line. How do I do that?
Making the line shorter to accommodate the size of the arrowhead won't really work. The size of the arrowhead depends on the thickness of the line (which is good), but I don't know the thickness because it can be specified in a style element that's already been written to the SVG document.
In this example, I'd like the the arrowhead entirely inside the square, with its tip at the square's corner, rather than sticking out of the square.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<g><marker id="arrowhead0" viewBox="0 0 60 60" refX="0" refY="30" markerUnits="strokeWidth" markerWidth="8" markerHeight="10" orient="auto">
<path d="M 0 0 L 60 30 L 0 60 z" fill="#800000" /> </marker>
<line marker-end="url(#arrowhead0)" x1="1" y1="1" x2="100" y2="100" stroke="#800000" />
<rect x="1" y="1" width="100" height="100" stroke="green" fill="none"/>
</g></svg>
Setting the refX atribute to 60 (which I think might be the width of the arrowhead when oriented pointing to the right) seems to fix this issue. Scaling the width seems to be fine, not sure about other attributes.
I am no SVG expert, just found this interesting and played with the attributes until I stumbled upon this solution, so take it with a grain of salt.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<g><marker id="arrowhead0" viewBox="0 0 60 60" refX="0" refY="30" markerUnits="strokeWidth" markerWidth="8" markerHeight="10" orient="auto">
<path d="M 0 0 L 60 30 L 0 60 z" fill="#800000" /> </marker>
<marker id="arrowhead1" viewBox="0 0 60 60" refX="60" refY="30" markerUnits="strokeWidth" markerWidth="8" markerHeight="10" orient="auto">
<path d="M 0 0 L 60 30 L 0 60 z" fill="#800000" /> </marker>
<marker id="arrowhead2" viewBox="0 0 60 60" refX="60" refY="30" markerUnits="strokeWidth" markerWidth="16" markerHeight="10" orient="auto">
<path d="M 0 0 L 60 30 L 0 60 z" fill="#800000" /> </marker>
<line marker-end="url(#arrowhead0)" x1="1" y1="1" x2="100" y2="100" stroke="#800000" />
<line marker-end="url(#arrowhead1)" x1="1" y1="100" x2="50" y2="50" stroke="#800000" />
<line marker-end="url(#arrowhead2)" x1="100" y1="1" x2="50" y2="50" stroke="#800000" />
<rect x="1" y="1" width="100" height="100" stroke="green" fill="none"/>
</g></svg>
refX and refY control that so adjust as necessary. E.g.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<g><marker id="arrowhead0" viewBox="0 0 60 60" refX="44" refY="34" markerUnits="strokeWidth" markerWidth="8" markerHeight="10" orient="auto">
<path d="M 0 0 L 60 30 L 0 60 z" fill="#800000" /> </marker>
<line marker-end="url(#arrowhead0)" x1="1" y1="1" x2="100" y2="100" stroke="#800000" />
<rect x="1" y="1" width="100" height="100" stroke="green" fill="none"/>
</g></svg>
Use "marker-start" instead of "marker-end", draw the arrowhead backwards, and swap the line's endpoints.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<g><marker id="arrowhead0" viewBox="0 0 60 60" refX="0" refY="30" markerUnits="strokeWidth" markerWidth="8" markerHeight="10" orient="auto">
<path d="M 60 0 L 0 30 L 60 60 z" fill="#800000" /> </marker>
<line marker-start="url(#arrowhead0)" x1="100" y1="100" x2="1" y2="1" stroke="#800000" />
<rect x="1" y="1" width="100" height="100" stroke="green" fill="none"/>
</g></svg>
Trying a basic example from Mozilla Docs and the top arrow is not oriented correctly (only in Ms Edge browser) : https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/orient
Is there any way to fix it for that browser?
Apparently orient="auto-start-reverse" doesn't work in edge so you will need to use orient="auto". For this instead of a polyline I'm using 2 lines with the origin in 10,90
svg{width:300px}
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<defs>
<marker id="arrow" viewBox="0 0 10 10" refX="5" refY="5"
markerWidth="6" markerHeight="6"
orient="auto-start-reverse">
<path d="M 0 0 L 10 5 L 0 10 z" />
</marker>
<marker id="dataArrow" viewBox="0 0 10 10" refX="5" refY="5"
markerWidth="6" markerHeight="6"
orient="-65deg">
<path d="M 0 0 L 10 5 L 0 10 z" fill="red" />
</marker>
</defs>
<line x1="10" y1="90" x2="90" y2="90" fill="none" stroke="black"
marker-end="url(#arrow)" marker-end="url(#arrow)" />
<line x1="10" y1="90" x2="10" y2="10" fill="none" stroke="black"
marker-end="url(#arrow)" marker-end="url(#arrow)" />
<polyline points="15,80 29,50 43,60 57,30 71,40 85,15" fill="none" stroke="grey"
marker-start="url(#dataArrow)" marker-mid="url(#dataArrow)"
marker-end="url(#dataArrow)" />
</svg>
See this pen: https://codepen.io/AmeliaBR/details/qjXoQd
"auto-start-reverse SVG marker ...... Doesn't work in Edge/IE (and other older browsers) and doesn't fallback nicely (you get a non-rotating marker instead)."
i have an svg graphic but wanted to mirror it without changing the coordinates of the line/stroke but swap the position of the arrowhead and circle… is there a more efficient way of doing this? one thing that i thought about is changing the angle of each arrowhead and circle but is tedious to do. another suggestion is using transform matrix. does anybody know how to do this? thanks in advance.
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="2000" height="2000" xmlns="http://www.w3.org/2000/svg">
<g>
<path fill="none" stroke="#4caf50" stroke-width="2" stroke-miterlimit="10" d="M195.2,75.3c28-11.5,60.9-18.1,96-18.1 c78.4,0,145.6,32.9,173.1,79.4" />
<g fill="#4caf50" id="test">
<polygon class="one" points="201.6,79 202.1,77.7 195.7,75.1 198.8,68.9 197.5,68.3 193.8,75.9"/>
<path class="two" d="M461.6,138.1c0.8,1.4,2.7,1.9,4.1,1.1s1.9-2.7,1.1-4.1c-0.8-1.4-2.7-1.9-4.1-1.1 C461.3,134.8,460.8,136.6,461.6,138.1z"/>
</g>
</g>
</svg>
This can be solved with the help of SVG markers. MDN and W3C
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="2000" height="2000" xmlns="http://www.w3.org/2000/svg">
<defs>
<marker id="arrow1" viewBox="0 0 20 20" refX="0" refY="10"
markerUnits="userSpaceOnUse" orient="auto"
markerWidth="20" markerHeight="20">
<polyline id="markerPoly1" points="0,0 20,10 0,20 2,10" fill="#4caf50" />
</marker>
<marker id="circle1" viewBox="0 0 10 10" refX="0" refY="5"
markerUnits="userSpaceOnUse"
markerWidth="10" markerHeight="10">
<circle cx="5" cy="5" r="5" fill="#4caf50"" />
</marker>
</defs
<g>
<path fill="none" stroke="#4caf50" stroke-width="2" stroke-miterlimit="10" d="M195.2,75.3c28-11.5,60.9-18.1,96-18.1 c78.4,0,145.6,32.9,173.1,79.4" style=" marker-start: url(#circle1); marker-end: url(#arrow1);
fill:none; stroke:green; stroke-width:2; " />
</svg>
Update
The angle of the marker can be changed using the attribute orient = ("180").
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="2000" height="2000" xmlns="http://www.w3.org/2000/svg">
<defs>
<marker id="arrowLeft" viewBox="0 0 20 20" refX="0" refY="10"
markerUnits="userSpaceOnUse" orient="170"
markerWidth="20" markerHeight="20">
<polyline id="markerPoly1" points="0,0 20,10 0,20 2,10" fill="#4caf50" />
</marker>
<marker id="arrowRight" viewBox="0 0 20 20" refX="0" refY="10"
markerUnits="userSpaceOnUse" orient="auto"
markerWidth="20" markerHeight="20">
<polyline id="markerPoly1" points="0,0 20,10 0,20 2,10" fill="#4caf50" />
</marker>
<marker id="circle1" viewBox="0 0 10 10" refX="0" refY="5"
markerUnits="userSpaceOnUse" orient="auto"
markerWidth="10" markerHeight="10">
<circle cx="5" cy="5" r="5" fill="#4caf50" />
</marker>
</defs>
<path id="path1" fill="none" stroke="#4caf50" stroke-width="2" stroke-miterlimit="10" d="M195.2,75.3c28-11.5,60.9-18.1,96-18.1 c78.4,0,145.6,32.9,173.1,79.4" style=" marker-end: url(#arrowRight); marker-start: url(#circle1);
fill:none; stroke:green; stroke-width:2; " />
<g transform="translate(0 100)" >
<path id="path1" fill="none" stroke="#4caf50" stroke-width="2" stroke-miterlimit="10" d="M195.2,75.3c28-11.5,60.9-18.1,96-18.1 c78.4,0,145.6,32.9,173.1,79.4" style=" marker-end: url(#circle1); marker-start: url(#arrowLeft);
fill:none; stroke:green; stroke-width:2; " />
</g>
</svg>