Getting mouse location in canvas [duplicate]

不羁岁月 提交于 2020-07-24 08:45:32

问题


Is there a way to get the location mouse inside a <canvas> tag? I want the location relative to to the upper right corner of the <canvas>, not the entire page.


回答1:


Easiest way is probably to add a onmousemove event listener to the canvas element, and then you can get the coordinates relative to the canvas from the event itself.

This is trivial to accomplish if you only need to support specific browsers, but there are differences between f.ex. Opera and Firefox.

Something like this should work for those two:

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



回答2:


The accepted answer will not work every time. If you don't use relative position the attributes offsetX and offsetY can be misleading.

You should use the function: canvas.getBoundingClientRect() from the canvas 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);



回答3:


Also note that you'll need CSS:

position: relative;

set to your canvas tag, in order to get the relative mouse position inside the canvas.

And the offset changes if there's a border




回答4:


I'll share the most bulletproof mouse code that I have created thus far. It works on all browsers will all manner of padding, margin, border, and add-ons (like the stumbleupon top bar)

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

You'll notice that I use some (optional) variables that are undefined in the function. They are:

  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;

I'd recommend only computing those once, which is why they are not in the getMouse function.




回答5:


For mouse position, I usually use jQuery since it normalizes some of the event attributes.

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 works for me in all the browsers.

EDIT:

I copied the code from one of my classes I was using, so the jQuery call to this.canvas was wrong. The updated function figures out which DOM element (targ) caused the event and then uses that element's offset to figure out the correct position.




回答6:


GEE is an endlessly helpful library for smoothing out troubles with canvas, including mouse location.




回答7:


Simple approach using mouse event and canvas properties:

JSFiddle demo of functionality http://jsfiddle.net/Dwqy7/5/
(Note: borders are not accounted for, resulting in off-by-one):

  1. Add a mouse event to your canvas
    canvas.addEventListener("mousemove", mouseMoved);

  2. Adjust event.clientX and event.clientY based on:
    canvas.offsetLeft
    window.pageXOffset
    window.pageYOffset
    canvas.offsetTop
    Thus:

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

The original question asked for coordinates from the upper right (second function). These functions will need to be within a scope where they can access the canvas element.

0,0 at upper left:

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

0,0 at upper right:

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



回答8:


I'd use jQuery.

$(document).ready(function() {

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

}

function canvasClick( e ){

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

}

This way your canvas can be anywhere on your page, relative or absolute.




回答9:


Subtract the X and Y offsets of the canvas DOM element from the mouse position to get the local position inside the canvas.



来源:https://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!