Creating digital art with canvas
feels like ✨ magic. ✨
It was originally introduced by Apple for their Safari and dashboard UI components, and (lucky for us) the Canvas API is now built-in to all modern browsers.
We can use it to create all sorts of awesome drawings, graphs, animations and games. Anything that you can imagine you can create. Sounds pretty awesome, right?
P.S. If you’ve ever heard people referring to a game as an HTML5 game, and wondered “how the heck is that possible because HTML is just a markup language!?” Well, now you know they meant they were using the canvas
HTML element & API.
Getting Started
Setting up a canvas is as simple as adding the canvas
element to your HTML and then hooking it up to your JavaScript file.
The HTML
- Add the
canvas
element inside the HTML body and give it an id ofcanvas
. You can set the size here as well with the width/height attributes. If you don’t specify a size, it will default to 300px (width) x 150px (height). Make sure to also include an alt tag to explain the canvas contents to provide context in the case of rendering issues and for accessibility. - Don’t forget to add the
script
tag to the end of the HTML body. We’ll be doing all of our drawing with JavaScript. 🎨
Tip: To make it easy to see your canvas you can add a border around it with CSS.
canvas { border: 1px solid black; }
The JavaScript
The Canvas API supports both 2D drawing as well as 3D drawing with WebGL. Let’s explore the 2nd dimension for now.
Note: Canvas paints with pixels, not with vectors (which SVGs use). For you designers out there: it’s akin to the difference between drawing with Photoshop (which uses pixels) vs. Illustrator (which uses vectors.)
- Define a Javascript variable named
canvas
which references the HTMLcanvas
element.
const canvas = document.getElementById("canvas")
- Everything that we draw is generated dynamically by JavaScript using the context object. The context object comes with the method
getContext()
which provides the rendering instructions (instructions differ between 2d and 3d). Define a context and specify thegetContext("2d")
method.
const context = canvas.getContext("2d")
- Alternate Sizing If you prefer, you can define the size of the canvas in your JavaScript (instead of in the HTML or CSS). Set the size of the canvas with the
canvas.width
andcanvas.height
properties. If you want your canvas to take up the entire page then you can set the size towindow.innerWidth
&window.innerHeight
canvas.width = window.innerWidth canvas.height = window.innerHeight //add \*0.5 if you want it to take up 1/2 the window
Now we’ve got ourselves a blank canvas— woo! 🖼 🥳
I love to create, and to me, the ultimate freedom of expression is a blank canvas or a block of clay to capture whatever emotions your imagination gives it.
Simple Drawing
Think of the canvas like a normal grid with an X- and Y-axis, but the origin is positioned in the top left corner (as opposed to the bottom left like you might have seen in math class.) The reason the origin is in the top left by default is because the page is rendered from top to bottom and left to right. Remember that, because it will be important again shortly.
Canvas gives us 2 basic shapes, which we can use as the building blocks for creating all other shapes — the rectangle and the path (line).
Rectangles
There are 3 methods we can use on the context object to work with rectangles. All of them take X, Y coordinates to specify the starting position (where you’d put your pen down on a piece of paper IRL) and a width, height to specify the size of the rectangle.
- Draw the outline of a rectangle.
context.strokeRect(x, y, width, height)
- Draw a rectangle that is filled in with a color (black by default).
context.fillRect(x, y, width, height)
- Clear the rectangle area (making it transparent).
context.clearRect(x, y, width, height)
Paths
A path is made up of a list of points on the grid, connected to each other with lines— like connect the dots!
There are a few steps involved in creating a path, which allow us to customize the path so we can create complex shapes.
- First, initiate a path with the
beginPath()
method.
context.beginPath()
- Specify a starting point.
context.moveTo(X,Y)
- Choose the next point on the path by specifying the next location.
context.lineTo(X,Y)
Repeat this as many times as necessary to create the shape you want.
- To close the path you can set the final point to be the same as the initial point, or you can use the
closePath()
method to automatically close the path.
context.closePath()
- Decide how thiccc you want your line to be. (There is no default thickness, so nothing will show up unless you specify one first.)
context.stroke()
Curves
So far everything we’ve drawn is made up of straight lines, but things are about to take a turn.
By default the line connecting each point (the sub-path) follows the most direct route, which is a straight line. But we can modify the sub-path to be as curvaceously indirect as we like with the arc()
method.
context.arc(x, y, radius, startAngle, endAngle)
The X,Y coordinates define the point in the center of the arc, the radius specifies the length of the arc, and the starting/ending angles specify how steep the curve is at the starting/ending points. If you’ve ever used the pen tool in a design program then this should make perfect sense. Essentially, these inputs are used to create a bezier curve.
Fin?
Now you know how to create shapes, but there is so much more that you can do with canvas
! As this has been titled “a short intro” I do believe I am limited by some unspoken word count. I’ll probably do a follow-up in the future, but for now I’ve included some links below that might serve as helpful next steps.
It’s so empowering to dream up something in your mind & then bring it to life with code. If you decide to create something, show me! I’d love to see what you are dreaming of.
Pssst. If you want to make something but don’t know where to start, the Odin Project has an assignment that requires you to use canvas to build an etch-a-sketch! Very fun and great for your portfolio. 😊