How to draw on an HTML Canvas with a Mouse

No Comments

Do you want to learn how to draw things on an HTML Canvas with a mouse? In this post, we will talk about some of the basic HTML canvas concepts, and you will learn how to create different forms like lines and rectangles on the canvas. After the basics, you will learn how to draw lines and rectangles with a mouse.

In this post, we will only go over the basics. In the next post, we will create a complete drawing app from scratch so if you are familiar with the basics and want to see them in action, head here.

In this post, we will cover the following topics:

Setup HTML

Before drawing anything on the canvas, we first have to set up our HTML and CSS. For that, we will have the following file structure.

drawing-basics/
├── js/
│   └── main.js
├── css/
│   └── style.css
└── index.html

To set up the project we will add the following contents to the index.html file.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Drawing Basics</title>
    <link rel="stylesheet" href="css/style.css">
</head>
<body>
    <canvas id="canvas"></canvas>
    <script src="js/main.js"></script>
</body>
</html>

As you can see, we created a simple canvas with the id “canvas” inside of the HTML and nothing more. For the styling, we will add the following contents to the stlye.css file:

html {
    height: 100%;
}

body {
    margin: 0;
    min-height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
}

#canvas {
    width: 70%;
    aspect-ratio: 16/9;
    border: 2px solid black;
}

With that, we have set the foundation to draw stuff on the canvas. The next step is to initialize the canvas!

Initialize the canvas

We first need to retrieve the canvas itself through a DOM Selector for this step. With the stored element, we then set the canvas’s context and can use this to draw stuff on it.

The canvas’s context will be set to ‘2d’ because we only want to draw two-dimensional pictures. The other possible canvas context is WebGL, but we will not cover it here.

So let’s do it for the canvas we created inside our HTML (all of the following code will be written inside of the js/main.js file):

const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");

The next step is to set the size of our canvas. In our case, we set that to 1920×1080 because we want an aspect ratio of 16/9, but you can set that however you want!

const height = 1080;
const width = 1920;

// resize canvas (CSS does scale it up or down)
canvas.height = height;
canvas.width = width;

Now that our canvas is set up, we will have a look at the basics.

Some Canvas Basics

In this section, we will have a look at how to draw different elements on top of the HTML canvas programmatically. Additionally, we will also check some of the possible customizations, like colors or the line width.

Create a Rectangle

The first thing we will look at is how to create a basic rectangle with the fillRect function. This function is part of the context that we created before, and it takes a start x, a start y, and a width and a height to draw the rectangle.

For example, to draw a rectangle in the position x=100, y=150 with width=200 and height=300 we can call the function like this:

context.fillRect(100, 150, 200, 300);

That was pretty simple, wasn’t it? Next, we will create a line, and believe it or not, that requires more effort than the rectangle^^

Create a Line

To draw a straight line, we have to perform four steps:

  1. Begin a new path with beginPath
  2. Define a start position with moveTo
  3. Set an end position with lineTo
  4. Draw the actual like with stroke

So, for example, we can draw a straight line from 50 100 to 100 150 like this:

// create a stroke
context.beginPath();
context.moveTo( 50, 100);
context.lineTo(100, 150);
context.stroke();
// this ends the current path
context.beginPath();

Change colors

Now that we learned how to draw things on the HTML canvas, you probably do not want everything in black, so let’s see how to update the colors!

For that, we have two properties we can change. The first one is fillStyle, and with that, you can define the fill color of the rectangles, for example. On the other hand, we have the strokeStyle property that you can use to change the color of strokes, for example, the line we drew before.

One important thing to note is that changing the styles only affects things that will be drawn afterwards!

So, to change the color of our next drawing to red we can change them like this:

context.strokeStyle = 'red';
context.fillStyle = 'red';

In this example, we used the keyword red to change the color, but you can also use hex values for that!

Change other styles

Some other styles that you can change are the line cap or the line width. For the line cap you can choose between three options: butt (flat end), round or square. For the line width, you can set numeric values that define how thick the strokes are.

Draw on the HTML Canvas with a Mouse

Draw a Line on the HTML Canvas with a Mouse

Now to the interesting parts where we see how to draw stuff on the HTML Canvas with a mouse! For that, we need to add the mousedown, mousemove, and mouseup event to the canvas!

With the mousedown event, we set a boolean called drawing to true to signal that we started drawing. Then, inside the mousemove event, we check if we are drawing and if that is the case, we draw a line on the current mouse position. Lastly, during the mouseup event, we set the boolean drawing to false again!

So, let’s create and attach these function, first the mousedown:

let drawing = false;

function startDrawing(e) {
    drawing = true;
    context.beginPath();
}

window.addEventListener("mousedown", startDrawing);

next the mouseup:

function endDrawing(e) {
    drawing = false;
}

window.addEventListener("mouseup", endDrawing);

and lastly the actual draw function:

function getMousePos(canvas, evt) {
    var rect = canvas.getBoundingClientRect(),
      scaleX = canvas.width / rect.width,
      scaleY = canvas.height / rect.height;
  
    return {
      x: (evt.clientX - rect.left) * scaleX,
      y: (evt.clientY - rect.top) * scaleY
    }
}

function draw(e) {
    if (!drawing) return;

    let { x, y } = getMousePos(canvas, e);

    context.lineTo(x, y);
    context.stroke();
}

window.addEventListener("mousemove", draw);

With that, we are now able to draw lines on our canvas. But to also draw dots on the canvas when we do a single click we also have to call draw inside of the startDrawing function:

function startDrawing(e) {
    drawing = true;
    context.beginPath();
    draw(e);
}

As you are probably seeing, it is not working yet. For it to work the line cap has to be square or round.

So, lastly, to fix the problem and for a smoother experience, we set the lineCap to round and the lineWidth to 10. We will call this after setting the width and height of the canvas!

context.lineWidth = 10;
context.lineCap = "round";

Draw a Rectangle on the HTML Canvas with a Mouse

Next, we will learn how to draw a rectangle on an HTML Canvas with a mouse. For that, we will utilize the mousedown and mouseup events.

But before we start, let’s remove the functions we created before from the event listeners by commenting out these lines:

//...
// window.addEventListener("mousedown", startDrawing);

//...
// window.addEventListener("mouseup", endDrawing);

//...
// window.addEventListener("mousemove", draw);

To create the rectangle, we store the start position during the mousedown event and then draw the rectangle during the mouseup event.

So let’s start with mousedown:

let start = {}

function startRect(e) {
	start = getMousePos(canvas, e);
}

window.addEventListener("mousedown", startRect);

and then the mouseup:

function endRect(e) {
    let { x, y } = getMousePos(canvas, e);
    context.fillRect(start.x, start.y, x - start.x, y - start.y);
}

window.addEventListener("mouseup", endRect);

With that, we are now able to draw rectangles on the canvas!

Responsive Canvas

One last thing I want to mention is the responsive canvas. I first thought that I would need to change the size of the canvas during the resize event, but this will empty the canvas and not bring the desired effect.

For me, CSS easily achieved the desired effect. The CSS only changes the visual width of the canvas because, during the initialization, we set a static width and height for the canvas. With that, it just scales down or up the resolution and does not change anything else!

Conclusion

In this post, we learned some of the HTML Canvas basics, including how to draw programmatically and different elements with a mouse!

You can find the written code inside of the repository here.

I hope the post helped you understand it better. If you have any questions feel free to send me a message through Twitter @programonaut or in the chat window on the right of your screen!

In case you liked this post and are interested in more guides like this one, consider subscribing to my newsletter. In it, I give an overview of all my posts written in a certain month (meaning you will get one mail a month!)

Discussion (0)

Add Comment

Your email address will not be published.