Creating a Paint Application with HTML5 Canvas

Let’s build a simple painting (or sketching) application using HTML5 <canvas> element along with its Javascript API. Although the app will be small, there’s going to be quite a bit of information for intake. So I’ll break the entire process into different tutorials (posts).

Features

A quick look at the features that we want in our little app:

What's the one thing every developer wants? More screens! Enhance your coding experience with an external monitor to increase screen real estate.

  1. Multiple tools to draw different shapes like a rectangle, circle or just a line.
  2. Multiple sizes for each tool.
  3. Multiple color choices.

The Markup

HTML code is going to be super simple.

<div id="sketch">
  <canvas id="paint"></canvas>
</div>

The Scripting

Onto the real part now, the Javascript coding. We’ll first set the height and width of the canvas and also get its 2D context.

var canvas = document.querySelector('#paint');
var ctx = canvas.getContext('2d');

var sketch = document.querySelector('#sketch');
var sketch_style = getComputedStyle(sketch);
canvas.width = parseInt(sketch_style.getPropertyValue('width'));
canvas.height = parseInt(sketch_style.getPropertyValue('height'));

We used window.getComputedStyle() along with getPropertyValue() to get the width and height of div#sketch. After applying parseInt() on the values, we set the width and height of the canvas to the same values. Neat approach towards a dynamic size!

Next up, we need to write the code for one of the most fundamental part of the app, i.e., mouse interaction.

var mouse = {x: 0, y: 0};

/* Mouse Capturing Work */
canvas.addEventListener('mousemove', function(e) {
  mouse.x = e.pageX - this.offsetLeft;
  mouse.y = e.pageY - this.offsetTop;
}, false);

So we have an object called mouse now that’ll hold the x and y co-ordinates of the mouse’s position relative to the canvas. e.pageX holds the position of the mouse relative to the document while this.offsetLeft holds the distance of the canvas’s upper left corner from the closest “positioned” parent. If none exists, then the closest positioned parent will default to body.

Subtracting offsetLeft/offsetTop from pageX/pageY helps us get the mouse positions relative to the canvas. At this point, it is important to note that this solution works in our case, but if your markup and styling is a bit more complex then try using some framework like jQuery to solve the problem of getting the left/top offset or check this stackoverflow thread for a pure JS solution.

Now the core part, that’ll do the drawing. It’s really simple, check out:

/* Drawing on Paint App */
ctx.lineWidth = 5;
ctx.lineJoin = 'round';
ctx.lineCap = 'round';
ctx.strokeStyle = 'blue';

canvas.addEventListener('mousedown', function(e) {
	ctx.beginPath();
	ctx.moveTo(mouse.x, mouse.y);

	canvas.addEventListener('mousemove', onPaint, false);
}, false);

canvas.addEventListener('mouseup', function() {
	canvas.removeEventListener('mousemove', onPaint, false);
}, false);

var onPaint = function() {
	ctx.lineTo(mouse.x, mouse.y);
	ctx.stroke();
};

On every mousedown event we begin a path and move the path to the mouse’s x/y points. We also bind a mousemove event at the same time, where the handler calls lineTo to draw lines on every x/y point through which the mouse passes. As soon as the mouse click is release, i.e., on mouseup, the event that’s attached to mousemove is detached. Simple enough!

Final Result

This is the demo of all the code that we discussed (when combined). Just drag your mouse on the canvas to draw random lines/shapes.


I definitely know that we’re not finished yet. But I think that’s a lot of information to digest for now. When you draw circles or lines, do you see the edges are not smooth, rather jagged ? That’s the exact problem we’re going to solve in the next part.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download

Author: Rishabh

Rishabh is a full stack web and mobile developer from India. Follow me on Twitter.

14 thoughts on “Creating a Paint Application with HTML5 Canvas”

  1. Hello! If you don’t mind I am using your code to develop my own application.(By the way I will cite you)
    The application I am making will be 3DS browser compatible, and DSi. Also adding tools for myself to use. 😛
    I think the biggest difference is I will be making it so you can save your cavas and upload it to a gallery.

  2. Hi Rishabh,
    Nice job and your tutorials helped me a lot. Can you also publish the various methods and properties and events associated with the canvas and context elements? That would be a great reference. Alternatively, can you point to a website which does that?
    Thanks
    Raghu

  3. I have copied your code as it is, but I dont find my application working. I just have a blank page. Should I include the JS after the div ID? Should I include any other libraries like Jquery?

  4. i have used your code, but when i draw something it is displayed at a offset and not at the exact location of my mousemoveover. can u help me out?

  5. Hey! I have some basics of HTML and am an artist would enjoy placing a quality sketching app on my website to keep an online sketchbook.
    I’ve noticed all your Javascript starts at code line #1, does that mean each JavaScript is a separate entity in the project site folder?

  6. Hello! I am creating a children’s website and would love to use this as a fun game for kids to play. I will be sure to cite you within the code. Would this be alright with you?

  7. I want to make a paint tool and using your codes I am able to make different shapes in canvas. But now I don’t understand how to resize the shapes individually. Any help?????……….

Leave a Reply

Your email address will not be published. Required fields are marked *