HTML5 Canvas paths mouseover

05 Apr

html5 canvas world map

Another map experiment in HTML5 Canvas this time. The main idea is to draw the world map with paths and fill each path with random colour on mouse hover.

You can see an example of this achieved with RaphaelJS and SVG in my previous post.

With HTML5 Canvas the task is not as straight forward as with SVG and it requires some work to be done to determine that mouse pointer is inside a given path. In theory context.isPointInPath(x, y) function should do just that according to the specification. But if your project has to work in earlier versions of IE and you are using ExCanvas for that then bad news – sPointInPath is not implemented yet.

Big thanks to Sam Hasler from for his idea to create second hidden canvas with the same paths, give each path a unique colour and fill the path with this colour. When user moves the mouse over the first visible canvas, get the coordinates of the mouse pointer and the colour of this pixel on the second hidden canvas. If the colour belongs to any of the paths then redraw the canvas and fill the hovered path with it’s colour.

For that we need the following HTML structure:

<!-- Second hidden canvas -->
<div id="shim" style="position:absolute; top: 0; left:0;"> 
    <canvas id="canvas2" width="800" height="500" style="background-color: #000"></canvas> 

<!-- First visible canvas -->
<canvas id="canvas" width="800" height="500" style="background-color: #000" onmousemove="mouseMoved(event)"> 
    <p>Your browser doesn't support canvas</p> 

Note that second canvas has to be located right below the first canvas. So if you position first canvas in the middle of the page, make sure second canvas is also centered.

Then on window load draw the paths on both canvases. But paths on the second canvas have to be filled in with unique colours.

When you user moves the mouse over the canvas, “mouseMoved(event)” function is executed. Here we get the colour of the current pixel, check if colour belongs to existing path and redraw the updated canvas.

function mouseMoved(event)
    // get mouse position x,y with a function of your choice
    var mousePos = getMousePosition(event);

    // get the data about pixel on the second canvas		
    var data = context2.getImageData(mousePos[0], mousePos[1], 1, 1).data;
    // get pixel colour
    var color = '#';
    for (var i=0, hex = ''; i<3; i++)
         hex = data[i].toString(16);
         hex = (hex.length==2) ? hex : '0'+hex;
    // get the path that colour belongs to
    var hoveredCountry = countryColours[color];
    // check that colour is different from colour at previous position e.g. mouse is not over the same country
    if ((currentColour != color) && (visitedCountries[hoveredCountry] === undefined) )
         // blank the canvas
         canvasEl.width = canvasEl.width;
         for (var sCountry in oWorldMap) 
             // draw the path
         // update the current colour

The drawback of course is that path colours have to be unique. If background colour is not solid, for example you use gradients, you might want to think of a different method.

View the demo here.

Leave a comment

Posted by on April 5, 2011 in HTML


Tags: , , , , ,

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: