How to draw an arrow in SVG? - html

I need to make it flexible. It can be some type of lines and arrows on the end of lines.
So, I decided to create two SVG objects: lines and an arrowhead.
How to draw an arrowhead on the end or beginning of the line?
My line is:
<svg width="500" height="100">
<line x1="0" y1="80" x2="100" y2="20" stroke="black" />
</svg>

You can use defs and path — http://jsfiddle.net/jxtfeqag/
<svg>
<defs>
<marker
id='head'
orient="auto"
markerWidth='3'
markerHeight='4'
refX='0.1'
refY='2'
>
<path d='M0,0 V4 L2,2 Z' fill="black" />
</marker>
</defs>
<path
id='arrow-line'
marker-end='url(#head)'
stroke-width='4'
fill='none' stroke='black'
d='M0,0, 80 100,120'
/>
</svg>

Related

Arrow not able to draw in exact 90 deg using div tag in html

I am drawing an arrow using div tag in html. It is working fine. But the issue is, when I am trying to draw it in exact 90 deg, it is disappearing. Can someone help me find the issue?
<div class="object-added arrowline" style="top:${shapeValues.top}px; left:${shapeValues.left}px">
<svg height="0" width="0">
<defs>
<marker id="markerArrow" markerWidth="13" markerHeight="13" refX="2" refY="6" orient="auto">
<path d="M2,2 L2,11 L10,6 L2,2" style="fill: #000000;" />
</marker>
</defs>
<defs>
<marker id="markerArrowEnd" markerWidth="13" markerHeight="13" refX="2" refY="6" orient="auto">
<path d="M10, 2 L10,11 L2,6 L10, 2" style="fill: #000000;" />
</marker>
</defs>
<line x1="0" y1="0" x2="0" y2="0" vector-effect="non-scaling-stroke" style="stroke:rgb(0,0,0);stroke-width:1" />
</svg>
</div>

How to create hamburger menu icon consisting from single SVG path

The SVG code of Material design Hamburger menu icon:
<svg style="width:24px;height:24px" viewBox="0 0 24 24">
<path fill="currentColor" d="M3,6H21V8H3V6M3,11H21V13H3V11M3,16H21V18H3V16Z" />
</svg>
However it always could be some reason I can not use the Material Design icon and need to create my own one. But how I can reach such simple code? One path.
Tried to draw the similar icon in AbodeXD. The output SVG code was:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="26" height="18" viewBox="0 0 26 18">
<defs>
<clipPath id="clip-アートボード_1">
<rect width="26" height="18"/>
</clipPath>
</defs>
<g id="アートボード_1" data-name="アートボード – 1" clip-path="url(#clip-アートボード_1)">
<line id="線_1" data-name="線 1" x2="26" transform="translate(0 0.5)" fill="none" stroke="#000" stroke-width="1"/>
<line id="線_2" data-name="線 2" x2="26" transform="translate(0 17.5)" fill="none" stroke="#000" stroke-width="1"/>
<line id="線_3" data-name="線 3" x2="26" transform="translate(0 9)" fill="none" stroke="#000" stroke-width="1"/>
</g>
</svg>
The SVG optimization reduced above code to:
<svg xmlns="http://www.w3.org/2000/svg" width="26" height="18">
<defs>
<clipPath id="a">
<path d="M0 0h26v18H0z"/>
</clipPath>
</defs>
<g data-name="アートボード – 1" clip-path="url(#a)" fill="none" stroke="#000">
<path data-name="線 1" d="M0 .5h26"/>
<path data-name="線 2" d="M0 17.5h26"/>
<path data-name="線 3" d="M0 9h26"/>
</g>
</svg>
But it a more complicated than Material Design SVG. Also, we can't change the icon color by like fill: red as many other icons.
Path syntax is easy to understand - let's break it down:
<path fill="currentColor" d="M3,6H21V8H3V6M3,11H21V13H3V11M3,16H21V18H3V16Z" />
M3,6 - Move the drawing point to coordinates [3,6]
H21 - draw a Horizontal line to coordinates [21,Current Y Coordinate (6)]
V8 - draw a Vertical line to coordinates [Current X Coordinate (21), 8]
H3 - draw a Horizontal line to coordinates [3,Current Y Coordinate (8)]
V6 - etc.
M3,11 - Move the drawing point to coordinates [3,11]
... etc
Z - Draw a line to the start of the current subpath (the coordinates of the last MoveTo - which in this case, doesn't do anything, because we're already at those coordinates)
So if you want the hamburger menu to be in a smaller viewBox, you can edit the path by hand like so:
<svg style="width:20px;height:20px" viewBox="0 0 20 20">
<path fill="currentColor" d="M1,4 H18 V6 H1 V4 M1,9 H18 V11 H1 V7 M3,14 H18 V16 H1 V14" />
</svg>
Please Use stroke="red" rather than using Fill="red"
Please find the Below updated code:
<svg xmlns="http://www.w3.org/2000/svg" width="26" height="18">
<defs>
<clipPath id="a">
<path d="M0 0h26v18H0z"/>
</clipPath>
</defs>
<g data-name="アートボード – 1" clip-path="url(#a)" fill="none" stroke="red">
<path data-name="線 1" d="M0 .5h26"/>
<path data-name="線 2" d="M0 17.5h26"/>
<path data-name="線 3" d="M0 9h26"/>
</g>
</svg>

SVG Isometric Box, overlapping lines

This is my first attempt at creating .svg images. I created an isometric view of a plate, but I noticed that when the image scales up, the lines do not intersect cleanly - they overlap (see image).
What am I doing wrong here?
<svg viewBox="0 0 100 60" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="greyGrad" gradientUnits="userSpaceOnUse">
<stop stop-color="#ddd" offset="0%"/>
<stop stop-color="#999" offset="85%"/>
</linearGradient>
</defs>
<g>
<polygon stroke="#333" points="0,0 8,14 11,14 3,0" fill="url(#greyGrad)"/>
<polygon stroke="#333" points="8,14 11,14 11,58 8,58" fill="url(#greyGrad)"/>
<polygon stroke="#333" points="0,0 8,14 8,58 0,45" fill="url(#greyGrad)"/>
</g>
</svg>
The problem is that mitred corners tend to stick out a long way at acute angles. The easy fix is to add stroke-linejoin="round" to your path elements, which will round them all off with the same radius.
But if you want sharp corners, you'll get better results if you draw the paths and fills separately, with the angles in the paths as large as possible. Here's an example. If you hover over the strokes, you should be able to see what's going on:
path:hover { stroke:#888; }
<!-- Cube consisting of three filled quads -->
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="180" viewBox="0 0 40 36">
<g stroke="#000" stroke-width="4">
<path d="M2,9 26,9 26,33 2,33Z" fill="orange"/>
<path d="M26,9 38,3 38,27 26,33Z" fill="red"/>
<path d="M2,9 14,3 38,3 26,9Z" fill="yellow"/>
</g>
</svg>
<!-- Cube with separate strokes and fills -->
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="180" viewBox="0 0 40 36">
<!-- Fills (no stroke) -->
<g stroke="none">
<path d="M2,9 26,9 26,33 2,33Z" fill="orange"/>
<path d="M26,9 38,3 38,27 26,33Z" fill="red"/>
<path d="M2,9 14,3 38,3 26,9Z" fill="yellow"/>
</g>
<!-- Strokes (outline first, then interior lines -->
<g fill="none" stroke="#000" stroke-width="4">
<path d="M2,9 14,3 38,3 38,27 26,33 2,33Z"/>
<path d="M2,9 26,9 38,3M26,9 26,33"/>
</g>
</svg>

How can I make the markers overlap perfectly so it doesn't appear twice for the same end?

I am trying to implement a highlight feature that makes the arrow bigger and changes its color. but the problem is when the width change, one of the two end markers (arrowhead) becomes bigger, but also doesn't overlap on the smaller one. how can I make it overlap so they appear as one bigger arrowhead instead of two
without highlight
with highlight
my code
render() {
const [start, target] = this.props.points;
const activeColor = !this.state.isActive ? "#6b6b6b" : "#ffa500";
const arrowWidth = !this.state.isActive ? "1" : "2";
return (
<g>
{
this.props.IsNotDot &&
<line
x1={start.x}
y1={start.y}
x2={target.x}
y2={target.y}
stroke={activeColor}
strokeWidth={arrowWidth}
strokeOpacity="0.7"
markerEnd="url(#arrowhead)"/>
}
</g>
);
}
Why not just create two separate marker definitions and show the correct one? You can swap the ID of the marker with a variable like you're doing for stroke color or by using CSS.
Note: I had to multiply the markerWidth, markerHeight, refX, and refY by the scale to get this to work. I think the reason for this is how SVG handles scaling strokes.
<svg>
<defs>
<marker id="arrowA"
markerWidth="10"
markerHeight="10"
refX="0" refY="3"
orient="auto"
markerUnits="strokeWidth">
<path fill="black" d="M0,0 L0,6 L9,3 z" />
</marker>
<marker id="arrowB"
markerWidth="30"
markerHeight="30"
refX="0" refY="9"
orient="auto"
markerUnits="strokeWidth">
<path
fill="orange" transform='scale(3)'
d="M0,0 L0,6 L9,3 z" />
</marker>
</defs>
</svg>
<svg id="lineA" width="276px" height="100px">
<line x1="64" y1="28" x2="200" y2="70"
stroke="black"
marker-end="url(#arrowA)">
</line>
</svg>
<svg id="lineB" width="276px" height="100px">
<line x1="64" y1="28" x2="200" y2="70"
stroke="black"
marker-end="url(#arrowB)">
</line>
</svg>
CSS to swap
#lineA {
cursor:pointer;
}
#lineA line {
marker-end: url("#arrowA");
}
#lineA:hover line {
stroke:orange;
marker-end: url("#arrowB");
}
<svg>
<defs>
<marker id="arrowA"
markerWidth="10"
markerHeight="10"
refX="0" refY="3"
orient="auto"
markerUnits="strokeWidth">
<path fill="black" d="M0,0 L0,6 L9,3 z" />
</marker>
<marker id="arrowB"
markerWidth="20"
markerHeight="20"
refX="0" refY="6"
orient="auto"
markerUnits="strokeWidth">
<path
fill="orange" transform='scale(2)'
d="M0,0 L0,6 L9,3 z" />
</marker>
</defs>
</svg>
<svg id="lineA" width="276px" height="100px">
<line x1="64" y1="28" x2="200" y2="70"
stroke="black" >
</line>
</svg>
Hover over the arrow

I want to draw this exact heart with paths in SVG in HTML5 and I don't know what I'm doing wrong

This is the heart I'm trying to draw:
Here's the code I've written:
<!DOCTYPE html/>
<html>
<head>
<title>SVG Paths</title>
</head>
<body>
<svg width="200px" height="200px">
<pattern id="rulerPattern" patternUnits="userSpaceOnUse"
x="0" y="0" width="10" height="10"
viewBox="0 0 10 10" >
<line x1="0" y1="0" x2="10" y2="0"
stroke="gray" fill="none" />
<line x1="0" y1="0" x2="0" y2="10"
stroke="gray" fill="none"/>
</pattern>
<rect x="0" y="0" width="100%" height="100%"
fill="url(#rulerPattern)" stroke="black" />
<path d="M 100 180 20 80 C20 80 60 -15 100 80"
stroke="black"
stroke-width="5"
fill="red" />
<path d="M 100 180 180 80 C180 80 140 -15 100 80"
stroke="black"
stroke-width="5"
fill="red" />
</svg>
</body>
</html>
What am I doing wrong? I want to get the exact shape of the heart shown on the first picture using paths.
The given svg specifies the semi-circles of the heart's top with the C subcommand of the path element. This subcommand creates a cubic spline which is ill-suited to the purpose since no segments of circles can be drawn with this family of curves (more about splines can be found here).
The following code rectifies the svg definition:
<!DOCTYPE html>
<html>
<head>
<title>SVG Paths</title>
</head>
<body>
<svg width="200px" height="200px">
<pattern id="rulerPattern" patternUnits="userSpaceOnUse"
x="0" y="0" width="10" height="10"
viewBox="0 0 10 10" >
<line x1="0" y1="0" x2="10" y2="0"
stroke="gray" fill="none" />
<line x1="0" y1="0" x2="0" y2="10"
stroke="gray" fill="none"/>
</pattern>
<rect x="0" y="0" width="100%" height="100%"
fill="url(#rulerPattern)" stroke="black"
/>
<path
d="M 180,80 L100,180 20,80 A 40,40 0,0,1 100,80 A 40,40 0,0,1 180,80"
stroke="black"
stroke-width="5"
fill="red"
/>
</svg>
</body>
</html>
The icon can be drawn with a single path. This path consists of a polyline to generate the lower portion of the heart and two adjacent semi-circles.
The syntax for the path definition is outlined in the svg specs at W3C. The complex part is the specification of the semi-circles which employ the elliptic arc command whose usage is detailed here.
NB: The DOCTYPE element is not an xml/html element, it closes without /.