Javascript 在画布中获取鼠标位置

Javascript 在画布中获取鼠标位置,javascript,html,canvas,Javascript,Html,Canvas,有没有办法将鼠标定位到标记中?我想要相对于右上角的位置,而不是整个页面。从鼠标位置减去canvas DOM元素的X和Y偏移量,以获得画布内部的本地位置。最简单的方法可能是向canvas元素添加onmousemove事件侦听器,然后,您可以从事件本身获取相对于画布的坐标 如果您只需要支持特定的浏览器,那么这是很容易做到的,但是f.ex之间存在差异。Opera和Firefox 这样的东西应该对这两个人有用: function mouseMove(e) { var mouseX, mouseY

有没有办法将鼠标定位到
标记中?我想要相对于
右上角的位置,而不是整个页面。

从鼠标位置减去canvas DOM元素的X和Y偏移量,以获得画布内部的本地位置。

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

如果您只需要支持特定的浏览器,那么这是很容易做到的,但是f.ex之间存在差异。Opera和Firefox

这样的东西应该对这两个人有用:

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 */
}

还要注意,您需要CSS:

位置:相对位置

设置为画布标记,以获取画布中鼠标的相对位置


如果鼠标位置有边框,偏移量就会改变,我通常使用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);
});
这在所有浏览器中都适用

编辑:


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

是一个无休止的有用库,用于解决画布的问题,包括鼠标位置。

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

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

我会使用jQuery

$(document).ready(function() {

    $("#canvas_id").bind( "mousedown", function(e){ canvasClick(e); } );

}

function canvasClick( e ){

    var x = e.offsetX;
    var y = e.offsetY;

}

这样,您的画布可以位于页面上的任何位置,相对的或绝对的。

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

您应该使用canvas API中的函数:
canvas.getBoundingClientRect()

  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);
使用鼠标事件和画布属性的简单方法: JSFIDLE功能演示
(注:不考虑边界,导致一次关闭):

  • 将鼠标事件添加到画布
    canvas.addEventListener(“mousemove”,mouseMoved)

  • 根据以下内容调整
    event.clientX
    event.clientY
    canvas.offsetLeft

    window.pageXOffset

    window.pageYOffset

    canvas.offsetTop

    因此:

    canvasMouseX=event.clientX-(canvas.offsetLeft-window.pageXOffset); canvasMouseY=event.clientY-(canvas.offsetTop-window.pageYOffset);

  • 原始问题要求从右上角获得坐标(第二个函数)。 这些函数需要位于可以访问canvas元素的范围内

    左上角为0,0:

    function mouseMoved(event){
        var canvasMouseX = event.clientX - (canvas.offsetLeft - window.pageXOffset);
        var canvasMouseY = event.clientY - (canvas.offsetTop - window.pageYOffset);
    }
    
    右上角为0,0:

    function mouseMoved(event){
        var canvasMouseX =  canvas.width - (event.clientX - canvas.offsetLeft)- window.pageXOffset;
        var canvasMouseY = event.clientY - (canvas.offsetTop - window.pageYOffset);
    }
    


    我强烈建议使用JQuery或其他标准化偏移量的javascript框架。只有当我将画布位置设置为Nat建议的相对位置时,这才对我有效。@Richard-这是因为对于未定位元素,
    layerX
    layerY
    相对于整个文档。有关更多信息,请参见我的回答:如果定义了e.offsetX,但等于0,则此代码做了错误的事情。如何以一种适用于所有浏览器的方式获取canvas dom元素的X和Y?看到拥有18k rep的人给出bunk建议总是很好的…介意告诉我为什么我的建议是“bunk”吗?你认为这是不正确的,不够详细的,等等?那会更有帮助。此外,我的代表并不一定意味着我的答案会是完美的,这就是为什么会有投票制度。你不同意吗?那就投反对票吧。你能解释一下我应该在答案中添加什么使它更好吗。我同意这是相当一般的,可能需要一个代码示例等。但到目前为止,人们只是说“答案不好”。你可以添加如何从DOM元素中获取(x,y)位置。一直在搜索互联网,以了解Firefox(7)为什么报告层的奇怪值-这修复了它,非常感谢!非常感谢。这就是我的问题。谢谢,在这之前我得到了不同的值。+1这修复了我在FF 11中遇到的5-10像素偏移问题。谢谢这不是唯一或必要的方法。这个答案应该解释的是,当画布是定位元素时,
    e.layerX
    e.layerY
    相对于画布,而当画布不是定位元素时,则相对于整个文档。请注意,这些特性不是任何标准的一部分。有更好的方法可以做到这一点。这个库对于链接来说是非常棒的thx。GEE不再被维护,开发者称之为“完全不推荐使用”。1像素的off-by-1像素是你的1px边框(边框和填充不算)。您还应该考虑滚动…干杯!:-)@马克:谢谢你的提醒;我已经调整了上面和JSFIDLE中的代码,以考虑滚动。我找不到调整画布边框的方法。很棒的小实用方法。我认为在大多数情况下,您不需要每次都计算画布偏移量。这应该是公认的答案
    function mouseMoved(event){
        var canvasMouseX = event.clientX - (canvas.offsetLeft - window.pageXOffset);
        var canvasMouseY = event.clientY - (canvas.offsetTop - window.pageYOffset);
    }
    
    function mouseMoved(event){
        var canvasMouseX =  canvas.width - (event.clientX - canvas.offsetLeft)- window.pageXOffset;
        var canvasMouseY = event.clientY - (canvas.offsetTop - window.pageYOffset);
    }