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.
- Multiple tools to draw different shapes like a rectangle, circle or just a line.
- Multiple sizes for each tool.
- 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.
hi Rishabh,
this is great article however it would not work on touch enabled devices. check out my post how to make simple drawing application which works on touchenabled browsers as well.
touch enabled canvas drawing
-regards
jignesh
Adding touch support is just a matter of binding proper handlers to the
touchstart
,touchmove
andtouchend
events.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.
Awesome, definitely go ahead and use it 🙂
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
This is a good reference for that exact purpose – http://net.tutsplus.com/tutorials/javascript-ajax/canvas-from-scratch-introducing-canvas/
Thanks
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?
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?
Nice Post! I made a similar one, but able to write. You can see a demo here -> http://www.webcamp.es/crear-paint-con-canvas-html5-y-jquery/
i hope you like it!!
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?
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?
For sure!