I need to draw nice stroked block arrow using SVG from one point (x0,y0)
to another (x1,y1)
, like the one on the picture.
The only way I can imagine is to use a line (two lines basically to simulate stroke and fill) with marker, but it looks kind of ugly due to overlaping strokes.
Ideally both line and marker should be filled with the same color and should have the same stroke color, and overall arrow width can be fixed (but if I could parametrize that as well it would be cool). Basically it should look the same as on picture provided and should be able to be drawn by just providing coordinates of two points. Is it even possible?
I was bored, so here you go. I have written a function to generate a path of the right shape.
You just need to give it the "from" and "to" coords, the line width, arrowhead width, and arrowhead length.
Enjoy!
var from = {x: 50, y: 250};
var to = {x: 250, y: 100};
var lineWidth = 30;
var arrowheadWidth = 60;
var arrowheadLength = 50;
var svg = document.getElementById("test");
drawArrow(svg, from, to, lineWidth, arrowheadWidth, arrowheadLength);
function drawArrow(svg, from, to, lineWidth, arrowheadWidth, arrowheadLength)
{
var dx = to.x - from.x;
var dy = to.y - from.y;
// Calculate the length of the line
var len = Math.sqrt(dx * dx + dy * dy);
if (len < arrowheadLength) return;
// The difference between the line width and the arrow width
var dW = arrowheadWidth - lineWidth;
// The angle of the line
var angle = Math.atan2(dy, dx) * 180 / Math.PI;
// Generate a path describing the arrow. For simplicity we define it as a
// horizontal line of the right length, and starting at 0,0. Then we rotate
// and move it into place with a transform attribute.
var d = ['M', 0, -lineWidth/2,
'h', len - arrowheadLength,
'v', -dW / 2,
'L', len, 0,
'L', len - arrowheadLength, arrowheadWidth / 2,
'v', -dW / 2,
'H', 0,
'Z' ];
var path = document.createElementNS("http://www.w3.org/2000/svg", "path");
path.setAttribute("d", d.join(' '));
path.setAttribute("transform", "translate("+from.x+","+from.y+") rotate("+angle+")");
path.setAttribute("class", "arrow-line");
svg.appendChild(path);
}
.arrow-line {
fill: gold;
stroke: black;
stroke-width: 6;
}
<svg id="test" width="300" height="300">
</svg>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With