HTML5 Canvas Tutorial: angles & paths

canvas hoeken en paden

The tutorial Canvas: lines and figures we discussed all the native lines and figures of the Canvas element. We can of course give many more examples of all kinds of lines and figures, but in this tutorial we are going a step further by drawing so called 'paths' on the Canvas element . The lines that we draw in the above mentioned tutorial are also examples of paths, however paths can be much more complicated, including multiple, interconnected, combinations of lines and curves. In this tutorial we will draw some of these more complex paths. Also, we will inspect the rounded corner and a number of ways by which you can stick lines together

1. Paths and subpaths

To draw a path on an HTML5 canvas we can connect multiple subpaths together. The endpoint of each subpath is also also a new context point. For each new subpath we have the methods lineTo () , arcto () , quadraticCurveTo () , and bezierCurveTo () at the disposal. If we want to draw a whole new path, we use the initial path () method.

context.beginPath();

Example 1. A path consisting of four subpaths (line - quadratic curv - quadratic curve -line). See image 1.

<!doctype html>
<html>
<head>
<script> 
    function drawPath() 
    {	
        var canvas=document.getElementById("figures");	
        var context=canvas.getContext("2d"); 	
        
        context.beginPath();
        context.moveTo(25,100);
        context.lineTo(75,100); // Sub pad 1: lijn
        context.quadraticCurveTo(125, -50, 175,100); // quadratic curve
        context.quadraticCurveTo(225, 250, 275,100); // quadratic curve
        context.lineTo(325, 100); // line 2
     
        context.lineWidth=5;
        context.strokeStyle="#f16529";
        context.stroke();
    }
    window.addEventListener("load", drawPath, true); 
</script>
</head>
<body>	
<canvas id="figures" style="border: 1px solid;" width="350" height="200">
</canvas>
</body>
</html>
Canvas met pad met subpaden
Image 1. Canvas element with path consisting of subpaths line - quadratic curve - quadratic curve - line

Example 2. Path consisting of four subpaths (line - quadratic curve - bezier curve - line). See image 1.

<!doctype html>
<html>
<head>
<script> 
    function drawPath() 
    {	
        var canvas=document.getElementById("figures");	
        var context=canvas.getContext("2d"); 	
        
        	context.beginPath();
			context.moveTo(25,20);
			context.lineTo(62,150); // line 1
			context.quadraticCurveTo(90, 228, 133,120); // quadratic curve
			context.bezierCurveTo(200, -40, 230, 150, 290, 100); // bezier curve
			context.lineTo(325, 70); // line 2
		 
			context.lineWidth=5;
			context.strokeStyle="#f16529";
			context.stroke();
    }
    window.addEventListener("load", drawPath, true); 
</script>
</head>
<body>	
<canvas id="figures" style="border: 1px solid;" width="350" height="200">
</canvas>
</body>
</html>
Canvas met pad met subpaden
Image 2. Canvas element with path consisting of subpaths line - quadratic curve - bezier curve - lineCanvas met pad met subpaden
Image 2a. Canvas element with path consisting of subpaths line - quadratic curve - bezier curve - line

Example 3. Path consisting of several Bézier curves. The figure includes a radial gradient fill. See image 3.

<!doctype html>
<html>
<head>
<script> 
    function drawPath() 
    {	
        var canvas=document.getElementById("figures");	
        var context=canvas.getContext("2d"); 	
        
        context.beginPath(); // begin tekenen van pad
        context.moveTo(70,80);
        context.bezierCurveTo(30, 100, 30, 190, 140, 150);
        context.bezierCurveTo(150, 180, 220, 180, 240, 150);
        context.bezierCurveTo(320, 150, 320, 120, 290, 100);
        context.bezierCurveTo(330, 40,270, 30, 240, 50);
        context.bezierCurveTo(220, 5,150, 20, 150, 50);
        context.bezierCurveTo(120, 5,50, 20, 70, 80);
		 // om de figuur weldra een vulling te geven dient het pad gesloten te worden
        context.closePath(); 
     
        var vulling=context.createRadialGradient(238,50,10,238,50,200);
        vulling.addColorStop(0,"#8ED6FF"); // lichtblauw
        vulling.addColorStop(1,"#004CB3"); // donkerblauw
        context.fillStyle=vulling;
        context.fill();
     
        context.lineWidth=7;
        context.strokeStyle="#004CB3";
        context.stroke();
    }
    window.addEventListener("load", drawPath, true); 
</script>
</head>
<body>	
<canvas id="figures" style="border: 1px solid;" width="350" height="200">
</canvas>
</body>
</html>
Canvas met pad met subpaden
Image 3. Canvas element with a path consisting of several Bézier curves and a radial gradient fill

2. The merging of lines

In the HTML5 Canvas API thera are three ways to connect paths with each other. Firstly we have the line join context property. This property can have the value miter, round or bevel. The default value is miter. The value of the line join property determines the appearance of the angle formed by connecting two lines: pointed, round or flattened. See image 4. Note that when the line thickness is very small, for example 1 px, then the the differences between the various line connections are barely visible.

 

context.lineJoin=[value];

Example 4. Three types of line connections: miter, round en square. See image 4

<!doctype html>
<html>
<head>
<script> 
    function showLineJoins() 
    {	
    
    	var canvas=document.getElementById("figures");
		var context=canvas.getContext("2d");

		 // miter line join (links)
        context.beginPath();
        context.moveTo(90,20); 
        context.lineTo(20,100); 
        context.lineTo(90,180); 
        context.lineWidth=25;
        context.lineJoin="miter";
        context.stroke();
     
        // round line join (midden)
        context.beginPath();
        context.moveTo(210,20); 
        context.lineTo(130,100); 
        context.lineTo(210,180); 
        context.lineWidth=25;
		context.strokeStyle="#ababab";
        context.lineJoin="round";
        context.stroke();
     
        // bevel line join (rechts)
        context.beginPath();
        context.moveTo(300,20); 
        context.lineTo(230,100); 
        context.lineTo(300,180); 
        context.lineWidth=25;
		context.strokeStyle="#dddddd";
        context.lineJoin="bevel";
        context.stroke();
    }
    window.addEventListener("load", showLineJoins, true); 
</script>
</head>
<body>	
<canvas id="figures" style="border: 1px solid;" width="350" height="200">
</canvas>
</body>
</html>
Canvas met lijn
Image 4. Three types of line connections, from left to right: miter, round en square.

3. Rounded corners

For the drawing of rounded corners in HTML5 Canvas we use the arcto () method which is defined by a a control point, an ending point, and a radius.

context.arcTo(controlX,controlY,endX,endY,radius);

Example 5. A line segment consisting of, successively, and connected: a line, a portion of a circle and a line again.

<!doctype html>
<html>
<head>
<script>
function roundedCorner(){    
var canvas = document.getElementById("figures");    
var context = canvas.getContext("2d");     
var rectWidth = 200;    
var rectHeight = 100;    
var rectX = canvas.width / 2 - rectWidth / 2;    
var rectY = canvas.height / 2 - rectHeight / 2;     
var cornerRadius = 50;     
context.beginPath();    
context.moveTo(rectX, rectY);    
context.lineTo(rectX + rectWidth - cornerRadius, rectY);    
context.arcTo(rectX + rectWidth, rectY, rectX + rectWidth, rectY + cornerRadius, cornerRadius);    
context.lineTo(rectX + rectWidth, rectY + rectHeight); 
context.strokeStyle="#f16529";    
context.lineWidth = 5;    
context.stroke();
}

window.addEventListener("load", roundedCorner, true); 
</script>
</head>
<body> 
<canvas id="figures" style="border: 1px solid;" width="350" height="200">
</canvas>
</body>
</html>
afgeronde hoek in HTML5 canvas
Image5. Canvas element with line with rounded corner.

Next tutorial

Leave a comment