Canvas relative position

I have been playing around with the canvas element in HTML5 and I am trying to get the canvas relative position.

I am using the layerX and layerY which seems like the most obvious solution but for some reason, and maybe this is just how it works the point that the layerX/Y sees is at the left corner of the pointer. my code is as follows

function ev_canvas (ev) {
    if (ev.layerX || ev.layerX == 0) { // Firefox
      ev._x = ev.layerX;
      ev._y = ev.layerY;
    } else if (ev.offsetX || ev.offsetX == 0) { // Opera
      ev._x = ev.offsetX;
      ev._y = ev.offsetY;
    }

It just adds the _x/y elements to the ev object so I can use them on a drawing surface.

Here is a video of what is happening to me:

http://img.zobgib.com/2011-03-21_1413.swf

If you want to play with it yourself you can at http://research.zobgib.com/beta

Do I just need to set a manual offset, or is layerX/Y wrong?

Edit:

I can add a manual offset but this seems like the WRONG way to go about putting the x/y positions in the proper place.

The code for the offset is just:

...
ev._x = ev.layerX-10;
ev._y = ev.layerY-13;
...

EDIT 2:

In Opera the cursor is a pointer and the position is correct by default.

In Chrome and Safari when you click (by default, without returning false) the cursor turns to a text selector and position is at the bottom of the text selector.

In Firefox the cursor is a pointer but the position is in the center of the hand.

  • Which a return false;

    • Safari on the mousedown/move the cursor remains a pointer but the position is off
    • Firefox remains the same as without return false
    • Opera still wins
    • Chrome the cursor remains a “mouse cursor” and the position is off.
  • With the offset

    • Safari is close to correct (slightly above)
    • Firefox slightly above
    • Opera WIN
    • Chrome correct

There must be a better way

P.S. I cannot test IE so any results on that would be nice

Answer

layerX and layerY return offsets relative to the entire document, unless the event occurs inside a postioned element. The simplest solution is to add:

#beta {
    position: absolute;
}

Alternatively, you can first get the position of the canvas in the document and calculate your offsets relative to those coordinates, as described in this previous answer: