Reputation:
I try to get mouse coordinates on a canvas which has borders defined in CSS. First, I have used a solution found out on this link to get the coordinates of a mouse over a canvas :
function getPosition(event)
{
var x = new Number();
var y = new Number();
var canvas = document.getElementById("canvas");
if (event.x != undefined && event.y != undefined)
{
x = event.x;
y = event.y;
}
else // Firefox method to get the position
{
x = event.clientX + document.body.scrollLeft +
document.documentElement.scrollLeft;
y = event.clientY + document.body.scrollTop +
document.documentElement.scrollTop;
}
x -= canvas.offsetLeft;
y -= canvas.offsetTop;
}
solution 1 the result of this method. You can see that coordinates have a shift of 10 pixels, i.e the width of canvas borders.
To fix this issue of border width, I modified like this :
var computedStyle = window.getComputedStyle(canvas,null);
var topBorder = parseInt(computedStyle.getPropertyValue("border-top-width"),10);
var leftBorder = parseInt(computedStyle.getPropertyValue("border-left-width"),10);
// (x,y) coordinates
x -= canvas.offsetLeft + leftBorder;
y -= canvas.offsetTop + topBorder;
But this doesn't work very well : I have a light shifting on the corners (1 or 2 px shifting) ; you can see the result of this modification on solution 2
I also tried to do :
function getPosition(event) {
var x, y;
var rect = canvas.getBoundingClientRect();
var computedStyle = window.getComputedStyle(canvas,null);
var topBorder = parseInt(computedStyle.getPropertyValue("border-top-width"),10);
var leftBorder = parseInt(computedStyle.getPropertyValue("border-left-width"),10);
var x = event.clientX - rect.left - leftBorder;
var y = event.clientY - rect.top - topBorder;
// Display coordinates
xspan.innerHTML = x;
yspan.innerHTML = y;
}
The result is shown on solution 3 and there's still a light shift of 1, 2 pixels for the inner corners of the board.
I would like put the (0,480) mouse coordinates in the inner left bottom of canvas, (0,0) at the inner left up corner, (480,0) at the right up corner and (480,480) in the right bottom corner.
How to deal with the "10 pixel" of borders width (see CSS) ?
I make you notice that, before calling getPosition
, I have added 0.5px to all canvas coordinates because, for example, a line drawn at i=1
with border-width equal to 1, must be drawn at x = 0.5.
If anyone could give me advices to get valid coordinates on this canvas taking account of the borders width.
Thanks
Upvotes: 0
Views: 888
Reputation: 3130
Do as @markE said and wrap your <canvas>
element inside a div:
<div id="game-wrapper">
<canvas id="game" width="481" height="481">
</canvas>
And give the border to the game-wrapper
div. Also make game-wrapper
to be display: inline-block;
so the border lays out correctly around the canvas.
Then your whole coordinate script could be this:
function getPosition(event) {
var x = event.layerX;
var y = event.layerY;
}
Aside from that, i think your real problem is that the cursor's pivot point is not at the tip of the cursor, but rather a couple of pixels away from it (at least in OSX). You can observe this by changing the cursor to crosshair:
cursor: crosshair;
You also asked about the valid way to do a coordinate system transformation. I've found that it's good to have some function that translates the "in-game" coordinates to actual canvas coordinates and back. In your case the 0.5px line you draw:
function Vector2(x,y) {
this.x = x;
this.y = y;
}
Vector2.prototype.toGameCoordinates() {
return new Vector2(
this.x - 0.5,
this.y - 0.5
);
}
Vector2.prototype.toCanvasCoordinates() {
return new Vector2(
this.x + 0.5,
this.y + 0.5
);
}
Upvotes: 1