I was aware of the usual method for finding the click position relative to the canvas, as has been documented before, which in brief is:
event.pageX
and event.pageY
values to get the position of the click relative to the documentcanvasEl.offsetLeft
/canvas.El.offsetTop
or using jQuery's $(canvasEl).offset()
, recursing up through parents if necessarySadly, this doesn't work when both the following are true:
Whenever I've come across this problem, even outside of WebComponents, my initial reaction has always been why is it so hard to get the coordinates of a click on a canvas? Surely that's pretty crucial? Shouldn't the coordinates be calculated for you already?
It turns out that they have, almost. As described elsewhere on SO, The canvas API has a method getBoundingClientRect()
which returns a DOMRect
(ClientRect
in Chrome):
{
x: 348,
y: 180.35000610351562,
width: 128,
height: 128,
top: 180.35000610351562,
right: 476,
bottom: 308.3500061035156,
left: 348
}
So the following will reliably get the coordinates of a tap/click relative to the canvas element, come scroll or high water:
var x = event.pageX,
y = event.pageY; // (or your preferred method, e.g. jQuery)
bounds = event.target.getBoundingClientRect();
x = x - bounds.left;
y = y - bounds.top;
The above is from Firefox; I found Chrome doesn't include the x
and y
properties, so probably best to stick to left
and top
. I haven't tested it on IE or Safari.
I hope this proves useful to someone else - it's been driving me nuts over the past few months. Many thanks to the questions and answers linked to here.
Finally, this answer is a neat solution whether you're using Polymer/WebComponents or not - it just so happens that that was my in-road into the problem and really threw the issue into relief.