Although HTML5’s formal specification is still under development, the technology is already growing in popularity. HTML5, as supported by many popular web browsers, already brings together a set of client-side technologies for producing highly interactive and responsive applications. One of the more talked-about parts of the HTML5 toolkit is the Canvas element. This new element provides a graphical drawing surface, allowing developers to create graphics and animations, similar to other client-side technologies such as Flash. The canvas element is quite easy to use, providing a quick and powerful starting point for creating a variety of client-side graphical applications.
Before getting started with the details behind implementing the HTML5 canvas paint application, let’s take a look at the actual paint app running in the web browser.
Notice the above page contains a “canvas” tag element within the page. This will serve as our drawing surface. All paint commands will be issued against the canvas element. We’ve also defined a couple of div objects, to serve as buttons for our toolbar. We simply color the div background and set a border, to simulate the appearance of a button. Once clicked, we’ll change the appearance of the div border, to simulate focus on the button.
With the HTML defined, we can start our initial programmatic hook to gain access to the canvas. This occurs within our init.js file.
We now have a web page with an HTML5 canvas element. The next step is to perform our logic upon loading the page. There are a variety of methods for doing this, such as overriding the “onload” event within the body tag. We can also simply include our init.js file and have it automatically add an event listener to the window, as follows:
The above code inserts a window event listener for the “load” event. The load event will then call our init() method after the page has loaded. The init() method is where the core of our HTML5 canvas initialization will occur.
When working with the HTML5 canvas, you’ll typically need to reference the canvas’s context object, which is where the drawing actually occurs. We can access the context by first obtaining a reference to the canvas element within the page, and then getting a reference to the “2d” context of the canvas. This occurs within the first 2 lines of our init() method, as shown below:
Note in the above code, we’ll also automatically adjust the width and height of the canvas to size to the window. This allows us to maximize the paint screen according to the window size. We also add a set of event listeners. The first listener is to handle the “mousemove” event. This will allow us to paint as the mouse is moved across the screen. We’ll also monitor the “click” event on the canvas, for stamping images on the screen when the mouse is clicked (if a stamp was selected by the user). Finally, we’ll add a set of listeners for each div button, to handle clicking the div and changing the color accordingly.
To get the basics of our paint program going, we’ll first handle the “mousemove” event by defining our onMouseMove() method, as follows:
The above code accesses the coordinates of the mouse in order to retrieve an x,y coordinate. We’ll then draw a line from the canvas’s current draw point to the mouse’s coordinate. As the mouse moves across the screen, this method will fire, drawing pixels along the way.
Note, the above code will continuously paint as the mouse moves, regardless if the user releases the mouse button. To only paint while the mouse button is clicked, you can toggle the value of “started” and handle it within the “click” event of the canvas.
As mentioned above about continuous paint, you can toggle the “started” variable in the click event handler. To keep our example simple, we’ll just include logic for displaying the image stamps upon clicking the canvas. You can certainly update the code to include painting on or off depending on holding down the mouse button as well. We’ll define our click event handler, as follows.
The above code simply checks if we’ve already set a stampId (which is set when the user clicks one of the stamp buttons), and if so, draws the image on the canvas by using the drawImage() method, built into HTML5.
If you notice in the initial HTML for the page, the image stamp div buttons include an IMG image tag. This displays the image on the button. It also allows us to copy the image to draw onto the canvas with the drawImage() method. In the above code sample, the first parameter to the drawImage() method can take a reference to an IMG tag. It will use the contents of the IMG tag to draw onto the canvas surface.
An example of the div tag, containing an image element, appears as follows from our HTML page:
Since we’ve also added listeners for handling the click events on the toolbar buttons, we can implement the onColorClick() method as follows:
The above code first closes and re-opens the canvas’s context. This allows us to select a new color for painting on the HTML5 canvas. We choose a new color with the context.strokeStyle attribute. We’ll also set a border around the toolbar div button, to highlight that the color is selected. Note, we also keep a copy of the last color selected, so we can unhighlight the button’s border when a new color is clicked.
We can fill the background of the HTML5 canvas with a color in the onFill() method that we’ve added a listener for. The code simply involves calling the context.fillStyle to select a color and then calling context.fillRect() to paint a rectangle with the width and height of the HTML5 canvas block.
We’ve already defined the actual painting of the image stamps when the user clicks the canvas. We now need to define the method for the button click event from the stamp toolbar button. Upon clicking the toolbar button for an image stamp, we’ll simply save the div id (which is passed to us from the original event listener hook) in the init() method. Later on, when the user clicks the canvas, we’ll paint the element associated with this Id, which happens to be the inner IMG image tag.
After painting on the HTML5 canvas, the user can save the image as an actual picture by using the HTML5 toDataURL() method. For our example, we’ll save the image as a PNG and write it to the page. The user can then right-click the image and save it to disk. The code appears, as follows:
This example has auto-draw enabled, meaning the application will continuously paint while the mouse is moved around the screen. This makes it easy for children to draw by just moving the mouse, without having to click. However, it’s easy to enhance the program to only paint while holding down the mouse button (as in most traditional paint programs) by making the following changes to paint.js:
HTML5 provides an interesting and powerful set of technologies for creating the next generation of client and web-based applications. With the HTML5 canvas element, software developers can create a large variety of graphical applications, including charts, animations, games, and more. Although HTML5 is still under specification, many modern web browsers already include full support, allowing developers to implement fully functioning HTML5 applications to enhance productivity and user interaction.
The source code for this example is available online in our GitHub repository.
This article was written by Kory Becker, Microsoft certified software developer and architect, providing C# ASP .NET web application development, database design, and mobile software development across a variety of domains for clients in both the business and consumer sectors.