在画布中获取鼠标位置

IT技术 javascript html canvas
2021-02-01 23:54:23

有没有办法将位置鼠标放在<canvas>标签内?我想要相对于 右上角的位置<canvas>,而不是整个页面。

6个回答

接受的答案不会每次都有效。如果您不使用相对位置,则属性 offsetX 和 offsetY 可能会产生误导。

您应该使用函数:canvas.getBoundingClientRect()来自画布 API。

  function getMousePos(canvas, evt) {
    var rect = canvas.getBoundingClientRect();
    return {
      x: evt.clientX - rect.left,
      y: evt.clientY - rect.top
    };
  }
  canvas.addEventListener('mousemove', function(evt) {
    var mousePos = getMousePos(canvas, evt);
    console.log('Mouse position: ' + mousePos.x + ',' + mousePos.y);
  }, false);
这应该是公认的答案
2021-03-26 23:54:23

最简单的方法可能是在画布元素上添加一个 onmousemove 事件侦听器,然后您可以从事件本身获取相对于画布的坐标。

如果您只需要支持特定的浏览器,这很容易实现,但 f.ex 之间存在差异。歌剧和火狐。

这样的事情应该适用于这两个:

function mouseMove(e)
{
    var mouseX, mouseY;

    if(e.offsetX) {
        mouseX = e.offsetX;
        mouseY = e.offsetY;
    }
    else if(e.layerX) {
        mouseX = e.layerX;
        mouseY = e.layerY;
    }

    /* do something with mouseX/mouseY */
}
@Richard - 那是因为layerXlayerY对于非定位元素整个文档有关更多信息,请在此处查看我的答案:stackoverflow.com/questions/5085689/...
2021-03-17 23:54:23
如果我按照 Nat 的建议将画布位置设置为相对位置,这仅对我有用。
2021-03-26 23:54:23
如果定义了 e.offsetX,但等于 0,则此代码做错了事情。
2021-04-04 23:54:23
我强烈建议使用 JQuery 或其他一些标准化偏移量的 javascript 框架。
2021-04-05 23:54:23

另请注意,您将需要 CSS:

位置:相对;

设置为您的画布标签,以获得画布内的相对鼠标位置。

如果有边框,偏移量就会改变

+1 这解决了我在 FF 11 中遇到的 5-10 像素偏移问题。谢谢!
2021-03-17 23:54:23
一直在互联网上搜索以找出为什么 Firefox (7) 报告 layerY 的奇怪值 - 这修复了它,非常感谢!
2021-04-01 23:54:23
谢谢!那是我的问题。
2021-04-01 23:54:23
这不是唯一必要的方法。什么这个答案应该已经说明的是,e.layerXe.layerY相对于画布时,它是一个定位的元素,但是相对于整个文档时,它不是。请注意,这些属性不是任何标准的一部分。有更好的方法来做到这一点。
2021-04-05 23:54:23
谢谢,在此之前我得到了不同的值。
2021-04-09 23:54:23

我将分享迄今为止我创建的最防弹的鼠标代码。它适用于所有浏览器以及各种填充、边距、边框和附加组件(如 stumbleupon 顶部栏)

// Creates an object with x and y defined,
// set to the mouse position relative to the state's canvas
// If you wanna be super-correct this can be tricky,
// we have to worry about padding and borders
// takes an event and a reference to the canvas
function getMouse = function(e, canvas) {
  var element = canvas, offsetX = 0, offsetY = 0, mx, my;

  // Compute the total offset. It's possible to cache this if you want
  if (element.offsetParent !== undefined) {
    do {
      offsetX += element.offsetLeft;
      offsetY += element.offsetTop;
    } while ((element = element.offsetParent));
  }

  // Add padding and border style widths to offset
  // Also add the <html> offsets in case there's a position:fixed bar (like the stumbleupon bar)
  // This part is not strictly necessary, it depends on your styling
  offsetX += stylePaddingLeft + styleBorderLeft + htmlLeft;
  offsetY += stylePaddingTop + styleBorderTop + htmlTop;

  mx = e.pageX - offsetX;
  my = e.pageY - offsetY;

  // We return a simple javascript object with x and y defined
  return {x: mx, y: my};
}

您会注意到我使用了一些在函数中未定义的(可选)变量。他们是:

  stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(canvas, null)['paddingLeft'], 10)      || 0;
  stylePaddingTop  = parseInt(document.defaultView.getComputedStyle(canvas, null)['paddingTop'], 10)       || 0;
  styleBorderLeft  = parseInt(document.defaultView.getComputedStyle(canvas, null)['borderLeftWidth'], 10)  || 0;
  styleBorderTop   = parseInt(document.defaultView.getComputedStyle(canvas, null)['borderTopWidth'], 10)   || 0;
  // Some pages have fixed-position bars (like the stumbleupon bar) at the top or left of the page
  // They will mess up mouse coordinates and this fixes that
  var html = document.body.parentNode;
  htmlTop = html.offsetTop;
  htmlLeft = html.offsetLeft;

我建议只计算一次,这就是为什么它们不在getMouse函数中。

很棒的小实用方法。我认为在大多数情况下,您也不需要每次都计算画布偏移量。
2021-03-16 23:54:23

对于鼠标位置,我通常使用 jQuery,因为它规范了一些事件属性。

function getPosition(e) {

    //this section is from http://www.quirksmode.org/js/events_properties.html
    var targ;
    if (!e)
        e = window.event;
    if (e.target)
        targ = e.target;
    else if (e.srcElement)
        targ = e.srcElement;
    if (targ.nodeType == 3) // defeat Safari bug
        targ = targ.parentNode;

    // jQuery normalizes the pageX and pageY
    // pageX,Y are the mouse positions relative to the document
    // offset() returns the position of the element relative to the document
    var x = e.pageX - $(targ).offset().left;
    var y = e.pageY - $(targ).offset().top;

    return {"x": x, "y": y};
};

// now just make sure you use this with jQuery
// obviously you can use other events other than click
$(elm).click(function(event) {
    // jQuery would normalize the event
    position = getPosition(event);
    //now you can use the x and y positions
    alert("X: " + position.x + " Y: " + position.y);
});

这在所有浏览器中都适用于我。

编辑:

我从我正在使用的一个类中复制了代码,因此对 jQuery 的调用this.canvas是错误的。更新后的函数找出哪个 DOM 元素 ( targ) 导致了事件,然后使用该元素的偏移量来确定正确的位置。