Canvas 2D Basics

Intro to HTML5 Canvas

Canvas was initially introduced by Apple for use in their Mac OS X WebKit component in 2004.

WebKit powered applications like Dashboard widgets and the Safari Browser. In 2005, it started being used in Gecko 1.8 (Firefox), and in Opera in 2006, and standardized by WHATWG (Web Hypertext Application Technology Working Group - remember them?) on new proposed specifications for next generation web technologies.

So what is canvas 2D?

The canvas tag/element is an HTML5 element which can be used to draw graphics using JavaScript.

The canvas element is only a container for graphics. You must use JavaScript to draw the graphics.

canvas can be used to draw graphs, combine photos, or create animations.

So who would use canvas 2D anyway?!

So many artists and designers. Top D.Js to enhance the club experience! So many developers!

I just added this slide this morning (Thursday, October 14, 2021) in response to a student who asked me "So who would use JavaScript anyway? IS it used in Television Production?"

Not in the physical T.V. But yes, in streaming. And these days, it's becoming more and more about that, and less and less about traditional Television Production. These days, we are all about being on the go, being remote, carrying our laptops, smart phones, or tablets with us wherever we go. Has anyone ever heard of carrying around a traditional T.V. for the sole purpose of viewing?

What spurred on this slide was some research I was doing for a site I am working on. I was looking up the history of Java, and came across the following information on javatpoint.com:

The history of Java is very interesting. Java was originally designed for interactive television, but it was too advanced technology for the digital cable television industry at the time.

This was in the early 1990s!

So I took my search a step further and found the following information on Quora:

At my previous company, I spent several years developing streaming video players on multiple TV platforms including Roku, Android, web and Chromecast but not the physical TV sets themselves ... A custom version of Javascript/HTML5 Canvas 2D was what Playstation used for its apps. I know Samsung’s SmartTV also used Javascript/HTML/CSS for creating apps for it. Like web, Chromecast uses HTML5/CSS/JS. It’s basically just broadcasting a webpage to your SmartTV. Adobe Flash was very popular until the past two years to develop streaming video for the standard HLS based M3u8 file format. A Javascript HLS library is also available for decoding such formats.

Companies like Netflix use JavaScript on the frontend and Node.js on the back end. Node.js permits them to use one language both in the front and back. Before Node.js, this was not possible. Companies had to use one language in the front and another in the back. For example, Netflix was using Java in the back end (they still use it for legacy reasons), but had to use JavaScript in the front end. With the advancements that have taken place in Nodejs since its first release in 2009.

canvas 2D is built with JavaScript. It is used by (many) artists, designers, developers, and numerous educational institutions and education-related companies use it as well (among others).

According to transperfect.com,

HTML5 is the Future of E-Learning ... While Flash is still around, here’s why the e-learning industry should embrace HTML5 as the new standard: The World is Going Mobile: According to Stat Counter, 52% of web content is currently browsed via mobile phones, compared to 25% three years ago, and 10% five years ago. This means that more users will want to view e-learning courses on a mobile phone, and Flash doesn’t work in mobile at all ... Another benefit is offline caching—an entirely new addition to HTML technology that enables webmasters to define which files the visitor's browser can save for offline reading, so users can revisit the content at any time ...

Basically, HTML5 refers to a set of modern web technologies. This includes the HTML Living Standard, along with JavaScript APIs to enhance storage, multimedia, and hardware access.

The list goes on and on.

Defining the canvas element

Defining the canvas element is as simple as adding the following to your index.html file:



                

canvas attributes

Aside from the id or class attribute (though usually you only see an id attribute set on the canvas element), the only other attributes one can set on the canvas element are the width and height attributes.



                

In addition, a closing canvas tag is necessary, otherwise the canvas content will not be displayed (shown above).

The default canvas size

default canvas size

If no width or height is set to the canvas element in index.html, in main.css, OR main.js, nothing will render to the page.

However, if ctx.fillRect(0,0,600,400) is set in main.js, for example, then the default canvas size of 300w x 150h would be rendered to the page.

If ctx.fillRect() is set to anything below 300w x 150h, up to or equal to that size, that is the size that will render to the page. Above that size, it will only render 300w x 150h.

The rendering context: intro

The canvas tag/element is intended to allow different styles of drawing.

To get access to the actual drawing interface, we first need to create a context. A context is an object whose methods provide the drawing interface.

There are two main drawing styles: "2d" for two-dimensional graphics, and "webgl" for three-dimensional graphics through the OpenGL interface.

The rendering context

The canvas element creates a fixed-size drawing surface that exposes one or more rendering contexts, which are used to create and manipulate canvas content.

In our case here, we are rendering the 2D canvas context.


// main.js
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
                

2d stands for two dimensional.

The first line of code here is familiar to us. We are querying the element with an id of "canvas".

Once we have retrieved the element with the id of "canvas", our canvas element, we can access the drawing context using the HTML5 canvas built-in .getContext() method.

In our index.html, we have:



                

Checking for canvas support in the browser


const canvas = document.getElementById("canvas");
let ctx = canvas.getContext("2d");
if (canvas.getContext) {
    ctx = canvas.getContext("2d");
} else {
    const para = document.querySelector(".unsupported");
    para.textContent = `Your browser does not support HTML5 Canvas.`;
}

First we declare and initialize a variable called canvas, and pass it a value of document.getElementById("canvas").

Then we declare and initialize a variable called ctx (short for context), and we pass it the value of the built-in .getContext("2d") method on the canvas variable (element), and pass a "2d" argument to the method. This means we want to use canvas 2d, which stands for 2 dimensional.

However, if we are not able to access canvas with the canvas.getContext() method, then we declare and initialize a para variable, and set it to document.querySelector(".unsupported"). That means we are querying an element, in this case a para ( p element ) variable containing the class name .unsupported.

Then we set the .textContent property on the para variable (p element) and pass it the value of `Your browser does not support HTML5 Canvas.` using a template literal.

canvas primitive shapes vs geometric primitives

The most common meaning of geometric primitives in computer graphics is the simplest (aka irreducible, meaning not able to further reduce or simplify) geometric objects that a system can draw or store. In constructive solid geometry, primitives are simple geometric shapes such as cubes, cylinders, spheres, cones, pyramids, and torus (special kind of 3 dimensional circle).

In modern 2d computer graphics, examples of primitives are lines, segments of straight lines, circles, and more complicated curves, as well as shapes such as boxes, polygons, and circles.

canvas primitive shapes

canvas supports only two primitive shapes: rectangles and paths.

paths are lists of points connected by lines, just like in Adobe Illustrator, for example.

All other shapes must be created by combining one or more paths. But there are a whole bunch of built-in canvas path drawing functions which help us to create complex shapes.

Functions that draw rectangles in canvas: fillRect()

There are 3 functions that draw rectangles in canvas. The first is fillRect().

The fillRect() method draws a rectangle that is filled according to the current fillStyle.

This method draws directly to the canvas without modifying the current path, so any subsequent fill() or stroke() calls will have no effect on it.

Syntax:


fillRect(x, y, width, height)
                

Parameters:

x: the x-axis coordinate of the upper-left corner of the rectangle (the x-axis coordinate starting point).

y: the y-axis coordinate of the upper-left corner of the rectangle (the y-axis coordinate starting point).

width: the rectangle's width. Positive values are to the right. Negative values are to the left.

height: the rectangle's height. Positive values are down. Negative values are up.

The .fillRect() method draws a rectangle with the help of the canvas 2D .fillStyle property.

.fillStyle property: specifies the color, gradient, or pattern to use inside shapes. The default style is #000.

fillRect()/.fillStyle: live example

To view (and play around with) some live code, we are going to visit the canvas 2D basics repository on Github and its local repository on my laptop.

Functions that draw rectangles in canvas: strokeRect()

The strokeRect() method draws a stroked rectangle whose starting point is at (x, y) and whose size is specified by width and height.

Syntax:


ctx.strokeRect(x, y, width, height);
                

Parameters:

x: the x-axis coordinate of the rectangle's starting point.

y: the y-axis coordinate of the rectangle's starting point.

width: The rectangle's width. Positive values are to the right, and negative values are to the left.

height: the rectangle's height. Positive values are down, and negative values are up.

Functions that draw rectangles in canvas: clearRect()

clearRect() sets the pixels in a rectangular area to transparent black (rgba(0,0,0,0)). The rectangle's starting corner is at (x, y) (upper left corner), and its size is specified by width and height.

Syntax:


ctx.clearRect(x, y, width, height);
                

Parameters:

x: the x-axis coordinate of the rectangle's starting point.

y: the y-axis coordinate of the rectangle's starting point.

width: the rectangle's width. Positive values are to the right. Negative values are to the left.

height: the rectangle's height. Positive values are down. Negative values are up.

Drawing a square with all three functions: live example

Now we head on back to my canvas 2d basics repository on Github to see the 3 square drawing functions in action: canvas 2d basics live site on Github.

All 3 rectangle functions draw immediately to the canvas.

Drawing to the canvas: paths

path: is a list of points connected by segments of lines that can be different shapes. They can be curved or not, and of different widths and colors.

A path, or a subpath, can be closed.

Extra steps to drawing paths

  • Draw a path.
  • Use drawing commands to draw into the path.
  • Once a path has been created, stroke() or fill() the path to render it.

Functions used to make shapes using paths: beginPath()

beginPath(): used as the first step to create a new path. Paths are stored as lists of subpaths (lines, arcs, etc) which together form a shape.

Each time this method is called, the list is reset and we can start drawing new shapes.

Drawing paths: moveTo()

When a current path is empty, as immediately after calling beginPath(), or after creating a new canvas, the first path building command always involves a call to moveTo().

Definition: moveTo() moves the path to a specified point in the canvas, without creating a line. It's similar to what the x-axis and y-axis coordinates do in the 3 rectangle functions.

Syntax:


ctx.moveTo(x,y);
                

Parameters:

x: the x coordinate of where to move the path to.

y: the y coordinate of where to move the path to.

Tip: use the stroke() method to draw the path on the canvas.

Drawing paths on the canvas: calling path methods

There are different path methods to call that specify the paths to be drawn. We'll get into this later.

Drawing paths: closePath()

closePath() closes a shape by drawing a straight line from the current point to the starting point. if the shape has already been closed or there's only one point in the list, this function does nothing.

Tip: Use the stroke() method to draw the path on the canvas.

Tip: Use the fill() method to fill the drawing (black is default). Use the fillStyle property to fill with another color/gradient.

Note: when you call fill(), any open shapes are automatically closed, so you don't have to call closePath(). This is not the case when you call stroke().

moveTo() revisited

moveTo() can be considered like a pen that is lifted from the page and moved to another spot on the page.

When canvas is initialized or beginPath() is called, you want to use the moveTo() function to place the starting point somewhere else.

moveTo() can also be used to draw unconnected paths.

Drawing paths on the canvas: rect()

rect(): creates a rectangular path whose starting point is at (x, y) and whose size is specified by width and height.

Syntax:


 ctx.rect(x,y,width,height);
                

Parameters:

x: x-coordinate of the upper-left corner of the rectangle (starting point).

y: y-coordinate of the upper-left corner of the rectangle (starting point).

width: the width of the rectangle in pixels. Positive values are to the right, and negative values are to the left.

height: the height of the rectangle in pixels. Positive values are down, and negative values are up.

Drawing paths on the canvas: rect() example


const centerX = canvas.width / 2.75;
const centerY = canvas.height / 3;
ctx.rect(centerX, centerY, 150, 100);
                

Drawing paths on the canvas: arc()

arc() method: creates arcs or curves used to create circles or parts of circles.

Syntax:


ctx.arc(x,y,r,startAngle,endAngle,counterClockwise);
                

Tip 1: to create a circle with the arc() method, set the start angle to 0, and the end angle to Math.PI * 2.

Tip 2: use the stroke() or fill() method to draw an arc() on the canvas.

Parameters:

x: the x coordinate of the center of the circle.

y: the y coordinate of the center of the circle.

r: the radius of the circle.

startAngle: the starting angle, in radians. 0 is at the 3 o'clock position of the arc's circle.

endAngle: the ending angle, in radians.

counterClockwise: optional. Specifies whether the drawing should be counterClockwise or clockWise. False is default, indicating clockWise, and true indicates counterClockwise.

Drawing paths on the canvas: arc() visualization

HTML5 canvas arc() Method visualization 1.

HTML5 Canvas arcs tutorial visualization 2.

Drawing paths on the canvas: radian

A radian is the standard unit of angular measure, used in many areas of mathematics. An angle's measurement in radians is numerically equal to the length of a corresponding arc of a circle.

One radian is just under 57.3 degrees, when the arc length is equal to the radius (analogous to an equilateral triangle).

A radian is represented by the symbol rad. An alternative symbol is the superscript letter c. A value of 1.3 radians could be written as 1.3 rad or 1.3c.

Drawing paths on the canvas: arc() example


ctx.arc(100, 50, 100, 0, 1.5 * Math.PI);
                

Related Resources