10

I'm trying to draw curved arrows in a html canvas. I have no problem to draw a curved line but I don't know how to put the > at the end of the line (direction).

ctx.beginPath();
  ctx.fillStyle = "rgba(55, 217, 56,"+ opacity +")";
  ctx.moveTo(this.fromX,this.fromY);
  ctx.quadraticCurveTo(this.controlX, this.controlY, this.toX, this.toY);
ctx.stroke();

My idea is taking a small part of the line at the end and draw a triangle. How can I get the coordinate of a point in the line?

Below is the image for better understanding.

Curve with arrow

deep
  • 159
  • 2
  • 9

1 Answers1

17

Since you're using a quadratic curve, you know two points that make a line that points in the "direction" of your arrow head:

enter image description here

So throw down a smidge of trig and you have yourself a solution. Here's a generalized function that will do it for you:

http://jsfiddle.net/SguzM/

function drawArrowhead(locx, locy, angle, sizex, sizey) {
    var hx = sizex / 2;
    var hy = sizey / 2;

    ctx.translate((locx ), (locy));
    ctx.rotate(angle);
    ctx.translate(-hx,-hy);

    ctx.beginPath();
    ctx.moveTo(0,0);
    ctx.lineTo(0,1*sizey);    
    ctx.lineTo(1*sizex,1*hy);
    ctx.closePath();
    ctx.fill();

    ctx.translate(hx,hy);
    ctx.rotate(-angle);
    ctx.translate(-locx,-locy);
}        

// returns radians
function findAngle(sx, sy, ex, ey) {
    // make sx and sy at the zero point
    return Math.atan2((ey - sy), (ex - sx));
}
Bartek Banachewicz
  • 38,596
  • 7
  • 91
  • 135
Simon Sarris
  • 62,212
  • 13
  • 141
  • 171
  • 5
    +1, only change I made here: http://jsfiddle.net/SguzM/1/ is change the use of `atan` to `atan2` to support negative angles and to prevent division by zero. – Variant Jul 05 '11 at 14:00
  • 2
    You should translate and rotate the canvas back to initial state after this operation so that canvas does not draw with the orientation set in this function. I added 3 lines at the end of drawArrowhead function, see here: http://jsfiddle.net/SguzM/89/ – tozlu Nov 17 '12 at 08:34
  • If you set sx = 100, sy = 20, ex = 100, ey = 10 then you get ugly looking arrow sadly. – lig Oct 09 '14 at 14:03
  • In case someone else also missed it, the two points that point in the "direction" of the arrow head are not the two points on the curve but the control point and the end point of the curve. – Existential Casper Apr 17 '21 at 09:55