Drawing in HTML Canvas
Get the project source code below, and follow along with the lesson material.
Download Project Source CodeTo set up the project on your local machine, please follow the directions provided in the README.md
file. If you run into any issues with running the project source code, then feel free to reach out to the author in the course's Discord channel.
This lesson preview is part of the Million Ether Homepage course and can be unlocked immediately with a \newline Pro subscription or a single-time purchase. Already have access to this course? Log in here.
Get unlimited access to Million Ether Homepage, plus 70+ \newline books, guides and courses with the \newline Pro subscription.
[00:00 - 00:08] To draw our pixels on a page, we first need to understand how to draw pixels on a canvas. In this video, we're going to quickly cover the HTML Canvas API and show how we can use it to draw colors.
[00:09 - 00:16] The first thing we need to do is add a canvas tag to our HTML page. In our canvas tag, we specify a width and height in the number of pixels that we want to show.
[00:17 - 00:26] In this case, we'll do a width of 1,000 and height of 1,000, because that will give us a million pixels. In source/index.js, the first thing we want to do is create a draw function.
[00:27 - 00:35] And we'll call this function when the body has loaded. Next, we need to fetch the canvas element from the page and start working with it.
[00:36 - 00:42] There are a few layers of APIs we need to go through to get to what we want. But what we're about to do is get the pixel data from the canvas and write new pixels onto it.
[00:43 - 00:52] The API can be a little involved at first, but I'll walk through each step and you can check out the canvas API documentation if you want to learn about the details. For more canvas, we get what's called a drawing context.
[00:53 - 01:00] In this case, we want a 2D context which lets us draw pixels. Next, we read the image data from the drawing context by using getImageData.
[01:01 - 01:14] The arguments mean we want to start at the first pixel, 0, 0, and capture the entire image up to canvas with canvas height. This returns an image data object, and the image data object has a data field which actually stores our pixels.
[01:15 - 01:19] Here's the problem though. Our data field is a one-dimensional array.
[01:20 - 01:25] We don't access this object with an x and y. Instead, each pixel is four positions.
[01:26 - 01:30] One for each red/green/blue alpha. So to access each pixel, we'll skip ahead by four.
[01:31 - 01:38] Let's try it out. Here we iterate over all the data and increment by four on each loop.
[01:39 - 01:48] Each pixel will be at index i plus an offset for the channel. So red is plus 0, green is plus 1, blue is plus 2, and alpha is plus 3.
[01:49 - 01:58] Let's set each pixel to some color we can test. Here we need to set the color to a number between 0 and 255.
[01:59 - 02:04] So I'll just modulo i with 255. Now that we have new pixels in the data, we have to print it out to the screen.
[02:05 - 02:09] We do that by using context.putImageData. Let's check it out on our screen.
[02:10 - 02:14] When we try this out, you can see that we have these grayish lines. Let's try removing the green and blue channels.
[02:15 - 02:29] Now notice that we get red and pink lines. What's happening here is that as i is incremented, we're setting a stronger value for both the red channel and the alpha.
[02:30 - 02:36] What if we wanted to show random colors? We could create this function, which will pick a somewhat random number between 0 and 255, and then pass it to each channel.
[02:37 - 02:52] What we get here is noise. It looks gross, but it's what we were going for.
[02:53 - 02:54] Play around with this and see if you can make something prettier.