Solar Confinement Solar Confinement - 7 months ago 61
Javascript Question

Real mouse position in canvas

I'm trying to draw with the mouse over a HTML5 canvas, but the only way that it seems to work well is if the canvas is in the position 0,0 (upper left corner) if I change the canvas position, for some reason it doesn't draw like it should. Here is my code.

function createImageOnCanvas(imageId){
document.getElementById("imgCanvas").style.display = "block";
document.getElementById("images").style.overflowY= "hidden";
var canvas = document.getElementById("imgCanvas");
var context = canvas.getContext("2d");
var img = new Image(300,300);
img.src = document.getElementById(imageId).src;
context.drawImage(img, (0),(0));
}

function draw(e){
var canvas = document.getElementById("imgCanvas");
var context = canvas.getContext("2d");
posx = e.clientX;
posy = e.clientY;
context.fillStyle = "#000000";
context.fillRect (posx, posy, 4, 4);
}


The HTML part

<body>
<div id="images">
</div>
<canvas onmousemove="draw(event)" style="margin:0;padding:0;" id="imgCanvas"
class="canvasView" width="250" height="250"></canvas>


I have read there's a way of creating a simple function in JavaScript to get the right position, but I have no idea about how to do it.

K3N K3N
Answer

You can get the mouse positions by using this snippet:

function getMousePos(canvas, evt) {
    var rect = canvas.getBoundingClientRect();
    return {
      x: evt.clientX - rect.left,
      y: evt.clientY - rect.top
    };
}

Just call it from your event with the event and canvas as arguments. It returns an object with x and y for the mouse positions.

As the mouse position you are getting is relative to the whole window you'll have to subtract the position of the element (here: canvas) to get it relative to the element. Canvas offers a neat boundary object which makes this rather simple as shown above.

Example of integration in your code:

//put this outside the event loop..
var canvas = document.getElementById("imgCanvas");
var context = canvas.getContext("2d");

function draw(e){
    var pos = getMousePos(canvas, e);
    posx = pos.x;
    posy = pos.y;

    context.fillStyle = "#000000";
    context.fillRect (posx, posy, 4, 4);
}

Working demo (with some modifications):
http://jsfiddle.net/AbdiasSoftware/ds9s7/