- HTML5 Canvas
- Javascript events
Tools Required:
- an HTML5 compliant browser
- your development IDE of choice (I am using Eclipse)
Drawing on the HTML5 canvas is deceptively simple. A quick object tag in the HTML and a bit of javascript to link to that canvas and context and you are off and running!
In this tutorial I went the route that one long and curvy drawn line is just really a smaller conglomeration of smaller lines that are tracked between a given start and end point (with an appropriate width and coloring).
At the heart - the canvas is a quick object call that you specify a height and width for - and if you are feeling generous a small message inside the tags for people who have browsers that are not quite up to snuff..
<canvas id="myCanvas" width="500" height="500"> Your browser doesn't support HTML5 canvas tags. </canvas>
Just a word of warning - my first inclination was to put the height and width in a CSS file, but javascript has a difficult time locating the values. It's best to keep them with the tag.
To draw on the canvas we need is to:
get an object that is the handle to the object.
Create a context from that handle
... and from there bob's your uncle!
http://www.w3schools...tml5_canvas.asp
In this example I am drawing a white square that should be in the top left corner and be fifty pixels big.
(FYI this code goes in your javascript file)
oCanvas = document.getElementById("myCanvas"); oContext = oCanvas.getContext("2d"); oContext.fillStyle = "#FFFFFF"; oContext.fillRect(0, 0, 50, 50);
To make this more interesting we are going to track the mouse movements and mouse clicks inside the canvas object. This requires us to hook into some javascript functionality and keep tabs on the mouse's location (remember we are drawing one big line with smaller little line segments), the user's selected width, and when the user is releasing the mouse click. One last bit of clean up - I will include a 'clear' button that takes all the rendered line segments and removes them to start a new canvas!
Here's the opening set of variables - tracking if the pen is down, the color, width, the canvas, context, and the mouse's location.
// -- Variables var bPenDown = false; // determine if the pen is down to write or not. var rgbLineColor = "FFFFFF"; // default color is white - this could be var lLineWidth = 1; // the line width holder // the context and canvas of our html5 canvas object var oCanvas; var oContext; // the point array to track the pen while it is down. var myPen = {}; window.onload = init;// just load the initialization when the form loads. // initalize our canvas and all the events we will need. function init() { // get the canvas object oCanvas = document.getElementById("myCanvas"); // set the context to plain 2d dreawing oContext = oCanvas.getContext("2d"); // setup the fill style to the default (white) oContext.fillStyle = "#" + rgbLineColor; // set the default selector for the pen document.getElementById("penWidth").selectedIndex = 1; // set the initial pen width lLineWidth = 3; // register the rest of the events. registerEvents(); }
The register events hooks into given canvas events and assigns their proper functions to call when fired. I am also hooking up the select drop down for the pen width (to quickly change the width when the user requests).
// the main events needed to be caught function registerEvents() { // mouse evens. oCanvas.onmousedown = mouseDownListener; oCanvas.onmousemove = mouseMoveListener; oCanvas.onmouseup = mouseUpListener; // if the user wants a new pen make sure to change the width. document.getElementById("penWidth").onchange = penWidthListener; }
The events are pretty straight forward with the exception of utilizing the event argument. The canvas events (especially the mouse movements) have an event arg that says "hey - when I was fired here was the mouse's location!". We can take those values and construct a begin and end point to draw!
/* * ============================== EVENTS ======================== */ // When the mouse is clicked in the canvas get the coordinates it is clicked and // set the boolean for the mouse is down function mouseDownListener(e) { // grab the event object which contains our mouse locations. var event = e || window.event;// IE -> window.event, not e // depeneding on where this canvas is we need to do a bit of math to get the // right coordinates var tempRect = oCanvas.getBoundingClientRect(); var mouseX = event.clientX - tempRect.left; var mouseY = event.clientY - tempRect.top; // send those coordinates to the the pen down and track'm penDown(mouseX, mouseY); } // When the mouse moves track that too! function mouseMoveListener(e) { var event = e || window.event; // IE -> window.event, not e // depeneding on where this canvas is we need to do a bit of math to get the // right coordinates var rect = oCanvas.getBoundingClientRect(); var mouseX = event.clientX - rect.left; var mouseY = event.clientY - rect.top; // draw a line with these two end coordiantes. penMove(mouseX, mouseY); } // When the mouse button is released function mouseUpListener(e) { // tell the drawing and pen boolean that we are done drawing. penUp(); } // when the pen is down start drawing save those coordinates as the start of the // line function penDown(x, y) { bPenDown = true; myPen.x = x; myPen.y = y; } // When the pen moves these coordinates are the 'end point' of the line we want // to draw. function penMove(x, y) { // only do this if the pen is down. if (bPenDown) { // Actually draw the line on our screen. drawLine(rgbLineColor, lLineWidth, myPen.x, myPen.y, x, y); // Shift the last points in as the start of the new line line myPen.x = x; myPen.y = y; } } // flips the boolean so we are not drawing lines when the mouse moves. function penUp() { bPenDown = false; }
All that is great, but the real meat is in the drawing, right? This is nothing more complex than the example of drawing a square, but here we are drawing a quick small line!
// takes the color, width, and two coordinates to draw a small line on the // canvas. function drawLine(color, thickness, x1, y1, x2, y2) { // we are storing the color in the database so add the hash mark. oContext.strokeStyle = "#" + color; oContext.lineWidth = thickness; // it's all about small paths oContext.beginPath(); oContext.moveTo(x1, y1); oContext.lineTo(x2, y2); oContext.stroke(); }
The final two events are the clear and the pen width events. The clear takes the context and just says "here's how big of an area I want to remove anything drawn on". In our case - the whole thing!
// clears the screen of the canvas and clears the coordinates from the table. function Clear_Down() { oContext.clearRect(0, 0, oCanvas.width, oCanvas.height); } // when the user selects a different pen - update our size. function penWidthListener(e) { lLineWidth = this.options[this.selectedIndex].value; }
In a more advanced section I will cover transmitting these values to other users who are on the same drawing page as well! Nothing beats collaborative work! (link)
Advanced topics you can try out:
- A color selector for the lines
- A background color changer
- Tightening up the timing to get a smoother line
- Adding shapes and other basic drawing polygons

Code
HTML
Spoiler
CSS
Spoiler
Javascript
Spoiler