Languages
[Edit]
EN

JavaScript - draw arrow on canvas element

8 points
Created by:
Kadeem-Craig
516

In this short aritcle, we would like to show how to draw arrow on canvas element using JavaScript.

By default there is not available defaul mechanism to draw array and it is necessary to create own one - what was presented in the article.

Quick solution:

// arrow = shaft + tip
//
// t argument indicates in % how big should be shaft part in drawn arrow
// t should be in range from 0 to 1
// t can be interpreted as: t = shaftLength / arrowLength
//
const drawArrow = (context, x1, y1, x2, y2, t = 0.9) => {
  	const arrow = {
        dx: x2 - x1,
        dy: y2 - y1
    };
  	const middle = {
        x: arrow.dx * t + x1,
        y: arrow.dy * t + y1
    };
    const tip = {
        dx: x2 - middle.x,
        dy: y2 - middle.y
    };
    context.beginPath();
    context.moveTo(x1, y1);
    context.lineTo(middle.x, middle.y);
  	context.moveTo(middle.x + 0.5 * tip.dy, middle.y - 0.5 * tip.dx);
    context.lineTo(middle.x - 0.5 * tip.dy, middle.y + 0.5 * tip.dx);
    context.lineTo(x2, y2);
    context.closePath();
    context.stroke();
};

    
// Usage example:
    
const canvas = document.querySelector('#my-canvas');
const context = canvas.getContext('2d');

drawArrow(context, 10, 50, 170, 150, 0.9);  // A=(10, 50)  B=(170, 150)  t=90% is shaft part share

Note: the above quick solution has better performance than solution based on trigonometric functions.

 

Preview: 

Drawing arrow on canvas using JavaScript.
Drawing arrow on canvas using JavaScript.

Practical example

In this section, you can find quick solution organized in more clear way.

// ONLINE-RUNNER:browser;

<!doctype html>
<html>
<head>
  <style>
    
    #my-canvas { border: 1px solid gray; }
    
  </style>
</head>
<body>
  <canvas id="my-canvas" width="200" height="200"></canvas>
  <script>

    function drawLine(context, x1, y1, x2, y2) {
        context.beginPath();
        context.moveTo(x1, y1);
        context.lineTo(x2, y2);
        context.stroke();
    }
    
    function drawHead(context, x1, y1, x2, y2, filled) {
        var dx = x2 - x1;
        var dy = y2 - y1;
        context.beginPath();
      	context.moveTo(x1 + 0.5 * dy, y1 - 0.5 * dx); // https://dirask.com/posts/jMqM0j
        context.lineTo(x1 - 0.5 * dy, y1 + 0.5 * dx); // https://dirask.com/posts/1GoW61
        context.lineTo(x2, y2);
        context.closePath();
        filled ? context.fill() : context.stroke();
    }
    
    // Draws arrow on the canvas.
    //
    // context - drawing context
    // x1, y1  - arrow staring point
    // x2, y2  - arrow ending point
    // arrow   - (optional) arrow head size (from 0 to 1 - relatively measured to arrow size)
    // filled  - (optional) if true, the arrow head should be filled with some color
    //
    function drawArrow(context, x1, y1, x2, y2, arrow, filled) {
      	if (arrow == null) {
        	arrow = 0.1;
        }
		var t = 1.0 - arrow;
      	var dx = x2 - x1;
      	var dy = y2 - y1;
      	var middleX = dx * t + x1;
      	var middleY = dy * t + y1;
        drawLine(context, x1, y1, middleX, middleY);
        drawHead(context, middleX, middleY, x2, y2, filled);
    }

    
    // Usage example:
    
    var canvas = document.querySelector('#my-canvas');
    var context = canvas.getContext('2d');

    drawArrow(context, 10, 50, 170, 150);  // context, x1, y1, x2, y2, (arrow: default=0.1 - arrow head size from 0 to 1)

  </script>
</body>
</html>

 

Arrow styles

In this section, you will see how to draw arrows using different styles.

Drawing styled arrow on canvas using JavaScript.
Drawing styled arrow on canvas using JavaScript.

Source code:

// ONLINE-RUNNER:browser;

<!doctype html>
<html>
<head>
  <style>
    
    #my-canvas { border: 1px solid gray; }
    
  </style>
  <script>

    function drawLine(context, x1, y1, x2, y2) {
        context.beginPath();
        context.moveTo(x1, y1);
        context.lineTo(x2, y2);
        context.stroke();
    }
    
    function drawHead(context, x1, y1, x2, y2, filled) {
        var dx = x2 - x1;
        var dy = y2 - y1;
        context.beginPath();
      	context.moveTo(x1 + 0.5 * dy, y1 - 0.5 * dx); // https://dirask.com/posts/jMqM0j
        context.lineTo(x1 - 0.5 * dy, y1 + 0.5 * dx); // https://dirask.com/posts/1GoW61
        context.lineTo(x2, y2);
        context.closePath();
        filled ? context.fill() : context.stroke();
    }
    
    // Draws arrow on the canvas.
    //
    // context - drawing context
    // x1, y1  - arrow staring point
    // x2, y2  - arrow ending point
    // arrow   - (optional) arrow head size (from 0 to 1 - relatively measured to arrow size)
    // filled  - (optional) if true, the arrow head should be filled with some color
    //
    function drawArrow(context, x1, y1, x2, y2, arrow, filled) {
      	if (arrow == null) {
        	arrow = 0.1;
        }
		var t = 1.0 - arrow;
      	var dx = x2 - x1;
      	var dy = y2 - y1;
      	var middleX = dx * t + x1;
      	var middleY = dy * t + y1;
        drawLine(context, x1, y1, middleX, middleY);
        drawHead(context, middleX, middleY, x2, y2, filled);
    }

  </script>
</head>
<body>
  <canvas id="my-canvas" width="400" height="200"></canvas>
  <script>
    
    // Usage example:
    
    var canvas = document.querySelector('#my-canvas');
    var context = canvas.getContext('2d');

    drawEmptyArrow(context, 10, 5, 170, 100, 0.04, 'blue', 0.2);    // 0.2px line width,  4% shaft
    drawEmptyArrow(context, 10, 30, 170, 125, 0.15, 'orange', 4);   //   4px line width, 15% shaft
    drawEmptyArrow(context, 10, 90, 170, 185, 0.4, 'gold', 1.5);    // 1.5px line width, 40% shaft

    drawFilledArrow(context, 210, 5, 370, 100, 0.04, 'blue', 0.2);  // 0.2px line width,  4% shaft
    drawFilledArrow(context, 210, 30, 370, 125, 0.15, 'orange', 4); //   4px line width, 15% shaft
    drawFilledArrow(context, 210, 90, 370, 185, 0.4, 'gold', 1.5);  // 1.5px line width, 40% shaft
    
    
    // Helper methods:
    
    function drawEmptyArrow(context, x1, y1, x2, y2, arrow, color, width) {
        context.lineWidth = width;
        context.strokeStyle = color;
        drawArrow(context, x1, y1, x2, y2, arrow, false);
    }
    
    function drawFilledArrow(context, x1, y1, x2, y2, arrow, color, width) {
        context.lineWidth = width;
        context.fillStyle = color;
        context.strokeStyle = color;
        drawArrow(context, x1, y1, x2, y2, arrow, true);
    }

  </script>
</body>
</html>

 

Donate to Dirask
Our content is created by volunteers - like Wikipedia. If you think, the things we do are good, donate us. Thanks!
Join to our subscribers to be up to date with content, news and offers.
Native Advertising
🚀
Get your tech brand or product in front of software developers.
For more information Contact us
Dirask - we help you to
solve coding problems.
Ask question.

❤️💻 🙂

Join