That’s Life

I’ve been playing with the <canvas/> element in HTML5 lately.  There’s a lot of little tutorials and cheat sheets out on the web, but nothing yet in the way of a comprehensive manual or cookbook.  Mostly I’d like to create little games and apps that run on the web, but also work well on smart phones and tablets.

My latest toy runs Conway’s game of life.  It runs fine on FireFox / Safari / Opera, and also on my iPod touch.

One puzzle that came up in this project was to translate the location of a mouse click into a position within the canvas.  This should be a pretty common problem, and you’ld think that all mouse events would have some canvasX / canvasY properties attached to tell the position relative to the canvas.  No such luck.  The closest thing are clientX and clientY which tell the absolute mouse location within the whole browser window.

You could calculate canvasX based on clientX if you know the absolute position of the canvas within the window, but again it’s not there.  The closest thing available is a positionLeft property telling the canvas’s relative position within it’s parent element.

Here’s my solution:

function calculateElementPosition(canvas) {
 if (canvas.positionLeft || canvas.positionTop) {
     return;
 }
 canvas.positionLeft = canvas.offsetLeft;
 canvas.positionTop = canvas.offsetTop;
 if (canvas.offsetParent) {
     calculateElementPosition(canvas.offsetParent);
     canvas.positionLeft += canvas.offsetParent.positionLeft;
     canvas.positionTop += canvas.offsetParent.positionTop;
 }
}

function calculatePosition(event, element) {
 if (event.canvasX || event.canvasY) {
     // Already calculated
 } else if (event.pageX || event.pageY) {
     event.canvasX = event.pageX - element.positionLeft;
     event.canvasY = event.pageY - element.positionTop;
 } else if (event.clientX || event.clientY) {
     event.canvasX = event.clientX + document.body.scrollLeft
         + document.documentElement.scrollLeft
         - element.positionLeft;
     event.canvasY = event.clientY + document.body.scrollTop
         + document.documentElement.scrollTop
         - element.positionTop;
 }
}

Calling calculatePosition within your event listener will attach the canvasX and canvasY properties to the mouse event.

Advertisements

No comments yet

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com 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 )

Google+ photo

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

Connecting to %s

%d bloggers like this: