如何获取 Polymer/WebComponent 中 canvas 上的 click/tap 的坐标(当在滚动容器内时)

How to get the coordinates of click/tap on canvas in Polymer/WebComponent (when inside scrolled container)

我知道查找相对于 canvas 的点击位置的常用方法 documented before,简而言之就是:

  1. 抓取 event.pageXevent.pageY 值以获取点击相对于文档的位置
  2. 减去页面上 canvas 的 x 和 y 坐标,使用 canvasEl.offsetLeft/canvas.El.offsetTop 或使用 jQuery 的 $(canvasEl).offset(),如有必要,递归 parents
  3. 减去页面的滚动位置和任何 parent 元素,如果有的话。

遗憾的是,当满足以下两个条件时,这将不起作用:

  1. canvas 是 Polymer 的一部分(我假设任何其他 WebComponent 解决方案可以填充 Shadow DOM)元素
  2. canvas 位于滚动 parent 内。我对此做了一些调查,看起来 Polymer 在穿过阴影边界时跳过了一个祖先,这意味着滚动偏移计算不正确。

每当我遇到这个问题时,即使是在 WebComponents 之外,我的第一反应总是 为什么很难获得 canvas 上的点击坐标?这当然很重要吗?坐标不是已经给你算出来了吗?

原来他们有,差不多。如 elsewhere on SO 所述,canvas API 有一个方法 getBoundingClientRect() 其中 returns 一个 DOMRectClientRect 在 Chrome):

{
    x: 348,
    y: 180.35000610351562,
    width: 128,
    height: 128,
    top: 180.35000610351562,
    right: 476,
    bottom: 308.3500061035156,
    left: 348
}

因此以下内容将可靠地获取 tap/click 相对于 canvas 元素的坐标,滚动或高水位:

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;

以上来自Firefox;我发现 Chrome 不包括 xy 属性,因此最好坚持使用 lefttop。我没有在 IE 或 Safari 上测试过。

我希望这对其他人有用 - 在过去的几个月里,它一直让我抓狂。非常感谢链接到此处的问题和答案。

最后,无论您是否使用 Polymer/WebComponents,这个答案都是一个巧妙的解决方案 - 碰巧这是我解决问题的方法,并真正解决了这个问题。