Getting a mouse in canvas

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

+41
javascript html5 canvas
Jul 11 '09 at 19:31
source share
9 answers

The easiest way is probably to add an 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 if you only need to support certain browsers, but there are differences between f.ex. Opera and Firefox.

Something like this should work for these 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 */ } 
+41
Jul 11 '09 at 20:10
source share
— -

The accepted answer will not work every time. If you are not using relative position, the offsetX and offsetY attributes 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); 
+34
Sep 27 '13 at 10:18
source share

Also note that you will need CSS:

position: relative;

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

And the offset changes if there is a border

+22
Jul 18 '10 at 7:28
source share

I will share the most bulletproof mouse code I have created so far. It works on all browsers, it will have all kinds of additions, fields, borders and add-ons (for example, the top panel of stumbleupon).

 // Creates an object with x and y defined, // set to the mouse position relative to the state 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 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 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 will notice that I use some (optional) variables that are undefined in the function. It:

  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 would recommend only calculating them once, so they are not in the getMouse function.

+16
May 4 '12 at 2:25 pm
source share

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

 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 browsers.

EDIT:

I copied the code from one of my classes that I used, so the jQuery call in this.canvas was wrong. The updated function determines which DOM element ( targ ) caused the event, and then uses this element offset to determine the correct position.

+7
Jul 01 2018-11-17T00:
source share

GEE is an infinitely useful library for smoothing canvas issues, including mouse location.

+6
Oct. 06 2018-11-11T00:
source share

A simple approach using mouse and canvas event properties:

JSFiddle demo function http://jsfiddle.net/Dwqy7/5/
(Note: borders are not taken into account, which leads to a step by step):

  • Add mouse event to canvas

    canvas.addEventListener("mousemove", mouseMoved);

  • Adjust event.clientX and event.clientY based on:
    canvas.offsetLeft
    window.pageXOffset
    window.pageYOffset
    canvas.offsetTop
    In this way:

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

The original question was asked for coordinates from the upper right (second function). These functions should be within the area where they can access the canvas element.

0,0 in the upper left corner:

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

0,0 in the upper right corner:

 function mouseMoved(event){ var canvasMouseX = canvas.width - (event.clientX - canvas.offsetLeft)- window.pageXOffset; var canvasMouseY = event.clientY - (canvas.offsetTop - window.pageYOffset); } 
+2
May 31 '14 at 19:56
source share

I would use jQuery.

 $(document).ready(function() { $("#canvas_id").bind( "mousedown", function(e){ canvasClick(e); } ); } function canvasClick( e ){ var x = e.offsetX; var y = e.offsetY; } 

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

+1
Apr 14 '13 at 16:40
source share

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

-one
Jul 11 '09 at 19:37
source share



All Articles