Draw with Your Mouse on an HTML Canvas

John Lindquist
InstructorJohn Lindquist
Share this video with your friends

Social Share Links

Send Tweet
Published 6 years ago
Updated 4 years ago

The canvas element exposes a 2d context which allows you to draw lines using the moveTo, lineTo, and stroke api. You can combine this with Mouse events to make a simple drawing app.

Instructor: [0:00] Let's start by creating a canvas with document-create-element-canvas, and we'll name this canvas. With that created, we can append it to the body-with-body-append-child-canvas.

[0:14] Then to be able to draw, we need to get the context off of the canvas. The 2-D context is the one we use for the drawing API. We'll name this context.

[0:27] To test if this is working, we can move to - to say where to start and then line through 100-100. That's where it'll draw a two. Context-stroke does the actual drawing. If I save here and refresh, you can see a line going from - to 100-100.

[0:48] First, we need to get rid of this margin here because the document body's margin does not default to zero, so let's go ahead and do that. Document-body-style-margin is zero. Now we refresh and that tucked that up in the corner.

[1:03] Then you'll notice if we try and draw it to the bottom of the screen -- I'll make the y-coordinate 1,000 and hit refresh -- it gets cut off right here rather drawing all the way to the bottom.

[1:14] To fix that we can say canvas-with is the same as the document-body-client-width, and then the same thing with height. We can client-height and canvas-height. Hit save there and refresh. Now it's going all the way to the bottom.

[1:32] To start our drawing, we'll do a canvas-add-event-listener and listen for mouse-move. We'll define a callback here where the event has the x- and y-coordinates to draw to, so we'll get those. They're called page-x and page-y. Grab those off the event. Page-x and page-y are essentially the x and y based on that top-left corner of the page.

[1:55] I'm going to rename those to x and y to save myself some typing. Then I'll grab these, cut and paste here. I'll say line to x and line to y, hit save, refresh. When I move my mouse, you can see it's drawing from - to wherever my mouse is.

[2:17] Instead of drawing from -, we're going to set up a previous point, or previous coordinate. I'll just name it previous. I'll say this is x- and y-. We'll say we move this to previous-x and previous-y.

[2:35] Then to start with, we're going to canvas-add-event-listener mouse-down, get the event here. We'll use the same page-x and page-y from here, paste it there, and say that previous is now x and y in this event.

[2:53] Now when we try this, we'll refresh. It's drawing from -. I click, now it's drawing from that point. I click, it's drawing from that point, click, and drawing from that point.

[3:04] Now while this looks really cool, what we actually want is previous to update every time the mouse moves. We'll say previous is x-y at the end of this block, so after it uses it, it will assign it to this new x and y. We'll hit save here and refresh. You can see as I move my mouse, it starts drawing.

[3:28] Finally, we want this to only draw if the mouse is down. I'll start with is-mouse-down and start that as false. When I click on mouse-down, I'll say is-mouse-down-is-true and then we'll create another event listener for mouse-up. We'll eat some of this and set is-mouse-down to false.

[3:54] Then I can wrap this entire block here inside of an if-statement, which checks if-is-mouse-down. We'll make our block, cut and paste that in there.

[4:07] Now when I refresh, I'll click the mouse, it'll start drawing. I hold the mouse down, I'll release the mouse, move the mouse around, click, start drawing, release, move the mouse around.

[4:19] Right now, the path here is a little jaggy and that has to do with our drawing path using a subpath based on move-to. Instead we can start a new path each time and to say context-begin-path. That will clear up our drawing a little bit.

[4:34] If I refresh, start drawing, you can see the path is a bit smoother now because each time I move the mouse, it's creating a new path. Then if you were to make the context line width something like 10, and I try drawing with something really thick, you can see there's some spaces in between, which is kind of a cool effect.

[4:57] If you want to remove that white space, you can change what's called the line-cap -- of-context-line-cap -- and set that to round. Each line will have rounded corners, which will fill in that gap between your drawing paths.

egghead
egghead
~ 2 hours ago

Member comments are a way for members to communicate, interact, and ask questions about a lesson.

The instructor or someone from the community might respond to your question Here are a few basic guidelines to commenting on egghead.io

Be on-Topic

Comments are for discussing a lesson. If you're having a general issue with the website functionality, please contact us at support@egghead.io.

Avoid meta-discussion

  • This was great!
  • This was horrible!
  • I didn't like this because it didn't match my skill level.
  • +1 It will likely be deleted as spam.

Code Problems?

Should be accompanied by code! Codesandbox or Stackblitz provide a way to share code and discuss it in context

Details and Context

Vague question? Vague answer. Any details and context you can provide will lure more interesting answers!

Markdown supported.
Become a member to join the discussionEnroll Today