What is the Canvas API?
The Canvas API consists of methods and properties that enable you to draw graphics with JavaScript. These graphics can be used for a variety of things, such as animations and game sprites.
Setup
In order to draw on the canvas, you first need to create one in your html
file.
<canvas id="my-canvas" height="600" width="800"></canvas>
You don't have to specify a height and width here. If you don't it will default to 300w x 150h, but you can set the dimensions using JavaScript.
Now you can get a reference to the canvas element and drawing context. When you draw with canvas, the drawing surface is actually the drawing context. The canvas element is like a container or frame for the drawing context. This post focuses on the 2D context, but there is a 3D context as well.
const canvas = document.getElementById('my-canvas');
const drawingContext = canvas.getContext('2d');
Rectangles
To draw a rectangle, you use the fillRect
method along with fillStyle
.
fillRect(x, y, width, height)
The x/y
values are the starting point of the rectangle and width/height
are the dimensions of the rectangle.
drawingContext.fillStyle = 'red';
drawingContext.fillRect(canvas.width/2 - 10, canvas.height/2 - 10, 20, 20);
You can also create a rectangle with an outline that isn't filled in.
drawingContext.strokeStyle = 'purple';
drawingContext.strokeRect(canvas.width/2 - 10, canvas.height/2 - 10, 20, 20);
Lines
Lines are slightly more complex than rectangles because you have to specify where their paths begin and end.
beginPath()
starts a new drawing path.
moveTo()
begins a new sub-path at the specified x,y coordinates. In other words, it's where you will begin your line.
lineTo()
is used to connect a straight line to the last point in the sub-path and specifies the x,y coordinates where you want your line to end.
strokeStyle
sets the color of the line. (default: black)
lineWidth
sets the width of the line. (default: 1)
stroke()
is used to actually draw the line.
Here are 2 different lines: A horizontal 1px wide purple line and a 3px wide diagonal red line.
drawingContext.beginPath();
drawingContext.strokeStyle = 'purple';
drawingContext.moveTo(10,15);
drawingContext.lineTo(290,15)
drawingContext.stroke();
drawingContext.beginPath();
drawingContext.lineWidth = 3;
drawingContext.strokeStyle = 'red';
drawingContext.moveTo(10,30);
drawingContext.lineTo(200,90)
drawingContext.stroke();
If you don't begin a new path, both of these lines would be red because the previous sub-path would still be part of the current path, and when you call stroke()
it would essentially paint over the purple line.
// Example without beginPath()
drawingContext.strokeStyle = 'purple';
drawingContext.moveTo(10,15);
drawingContext.lineTo(290,15)
drawingContext.stroke();
drawingContext.lineWidth = 3;
drawingContext.strokeStyle = 'red';
drawingContext.moveTo(10,30);
drawingContext.lineTo(200,90)
drawingContext.stroke();
In some instances you might want this behavior. For example, if for some reason you want to create a stroke through a previous bigger stroke while also creating a new stroke:
drawingContext.lineWidth = 60;
drawingContext.strokeStyle = 'blue';
drawingContext.moveTo(0, canvas.height/2);
drawingContext.lineTo(canvas.width, canvas.height/2);
drawingContext.stroke();
drawingContext.lineWidth = 10;
drawingContext.strokeStyle = 'red';
drawingContext.moveTo(0, canvas.height/2 + 20);
drawingContext.lineTo(canvas.width, canvas.height/2 + 20);
drawingContext.stroke();
Since I didn't begin a new path, when I created the 10px red line it stroked the new path as well as the previous path with a 10px red line.
Line Caps
There are 3 options to alter the look of the ends of your lines: butt
, round
, or square
. butt
ends are default; the ends are squared off at the endpoints. round
ends are, well, rounded, and a semicircle is added to the ends of the line. square
adds a box with an equal width and half the height of the lines thickness to the ends. butt
is the only end that stops at the exact points you specify; the others extend beyond your specified endpoints.
// default
drawingContext.beginPath();
drawingContext.lineWidth = 20;
drawingContext.moveTo(20, 20);
drawingContext.lineTo(canvas.width-20, 20);
drawingContext.stroke();
// round
drawingContext.beginPath();
drawingContext.lineCap = 'round';
drawingContext.lineWidth = 20;
drawingContext.moveTo(20, 50);
drawingContext.lineTo(canvas.width-20, 50);
drawingContext.stroke();
// square
drawingContext.beginPath();
drawingContext.lineCap = 'square';
drawingContext.lineWidth = 20;
drawingContext.moveTo(20, 80);
drawingContext.lineTo(canvas.width-20, 80);
drawingContext.stroke();
Next up: Complex Shapes
Top comments (0)