Finding out the mouse click position on a canvas with Javascript

February 13th, 2010 at 3:06 pm

I’m playing around with the HTML5 <canvas> element. One interesting thing to do is interact with the canvas using the mouse.

First we attach the mouse click event to the canvas (suppose we have an HTML page with a canvas element named canvas, and Game is a global "namespace object"):

Game.canvas = document.getElementById('canvas');
Game.canvas.addEventListener('click', on_canvas_click, false);

Now, in the event handler function, we can play with the event object. It has the clientX and clientY properties for finding out where the mouse was clicked, but these give imprecise results!

The reason for that is that the canvas itself isn’t placed at 0,0 on the client area. Therefore, we have to subtract its offset from the event’s coordinates, like this:

function on_canvas_click(ev) {
    var x = ev.clientX - Game.canvas.offsetLeft;
    var y = ev.clientY - Game.canvas.offsetTop;

    // ... x,y are the click coordinates relative to the
    // canvas itself
}

Edit (05.05.2010): If the window is scrolled (which is unlikely for a JS canvas application, but might happen in some cases) the method above will give wrong results. You’ll have to adjust for the scroll with $(window).scrollTop() (or scrollLeft() for horizontal scrolling).

Related posts:

  1. A simple canvas-based Javascript game, with a Django back-end
  2. The server-side Javascript meme
  3. Great Firefox productivity tip
  4. Finding out where a function was called from
  5. Table in Perl::Tk

2 Responses to “Finding out the mouse click position on a canvas with Javascript”

  1. SaturnPollyNo Gravatar Says:

    A short note on offsetLeft/offsetTop: Unless the canvas itself is moved (which should rarely be the case) the offsets of the canvas should be cached, because reading the offsets of an element causes the browser to do a reflow (http://www.phpied.com/rendering-repaint-reflowrelayout-restyle/). It’s not a big problem in combination with click-events, but sooner or later somebody will come along, c&p this and then use it in combination with ‘mousemove’. ;)

  2. Daniel ChristopherNo Gravatar Says:

    Just to say that the object.scrollLeft and object.ScrollTop are properties and not methods, so should be written without brackets.
    But thanks for this. :)

Leave a Reply

To post code with preserved formatting, enclose it in `backticks` (even multiple lines)