I am messing around with HTML5 right now and I wanted to program a little browser games - just for fun. I created a canvas in which a background image is loaded - its kind of a hexagonal grid. To find out which hexagon is clicked I use circles an their centers/radius. I explain this, because this way you can understand the code I post more quickly.
This all works really fine until I use the scrollbars - then everything is messed up. It just seems that I does't get the coordinates right. Because the grid is a little bit bigger, I have to use scrollbars especially on smaller screens.
So here is the code
The Website
<html>
<head>
<script type="text/javascript" src="worldmap.js"></script>
<script type="text/javascript" src="worldmapMouseEvents.js"></script>
</head>
<body onload="draw()">
Xcoord: <div id="xcoord">0</div>
Ycoord: <div id="ycoord">0</div><br>
Spalte: <div id="column">0</div><br>
Reihe: <div id="row">0</div><br>
<canvas id="canvas"
width="1100"
height="1100"
style="border: 1px solid black;"
onmousemove="getMousePosition()"
onmousedown="getCell()">
</canvas>
</body>
</html>
The file worldmap.js which displays the grid
function draw(){
var c=document.getElementById("canvas");
var ctx=c.getContext("2d");
var img = new Image();
img.onload = function(){
ctx.drawImage(img,0,0);
ctx.stroke();
};
img.src = './pics/grid.jpg';
}
And here the more source file worldmapMouseEvents.js which acts strangely after scrolling
function getMousePosition() {
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
{
x = event.clientX + document.body.scrollLeft
+ document.documentElement.scrollLeft;
y = event.clientY + document.body.scrollTop
+ document.documentElement.scrollTop;
}
x -= canvas.offsetLeft;
y -= canvas.offsetTop;
return [x,y];
}
Here the function that calculates which hexagon is clicked by using circles (The math is correct and its pretty simple to (xCoord - xCenter)^2 + (yCoord -yCenter)^2. If the radius^2 is equal or smaller its the point is within the circle. Those arrays in the beginning are just center coordinates of the grid.)
function getCell(){
var xOddRows = new Array(25, 65, 105, 145, 185, 225, 265, 305, 345, 385, 425, 465, 505, 545, 585, 625, 665, 705, 745, 785, 825, 865, 905, 945, 985);
var yOddRows = new Array(35, 115, 195, 275, 355, 435, 515, 595, 675, 755, 835, 915, 995);
var xEvenRows = new Array(45, 84, 125, 165, 205, 245, 285, 325, 365, 405, 445, 485, 525, 565, 605, 645, 685, 725, 765, 805, 845, 885, 925, 965, 1005);
var yEvenRows = new Array(75, 155, 235, 315, 395, 475, 555, 635, 715, 795, 875, 955);
var position = getMousePosition();
var x = position[0];
var y = position[1];
for(var yOddRowsRunner = 0; yOddRowsRunner < 13; yOddRowsRunner++){
for( var xOddRowsRunner = 0; xOddRowsRunner < 25; xOddRowsRunner++){
var circle = (x - xOddRows[xOddRowsRunner])*(x - xOddRows[xOddRowsRunner]) + (y - yOddRows[yOddRowsRunner])*(y - yOddRows[yOddRowsRunner]);
var radius = (20 * 20);
if(radius >= circle){
yPos = (2 * yOddRowsRunner) +1 ;//This is just for nicer output
return [yPos, xOddRowsRunner];
}
}
}
for(var yEvenRowsRunner = 0; yEvenRowsRunner < 12; yEvenRowsRunner++){
for( var xEvenRowsRunner = 0; xEvenRowsRunner < 25; xEvenRowsRunner++){
var circle = (x - xEvenRows[xEvenRowsRunner])*(x - xEvenRows[xEvenRowsRunner]) + (y - yEvenRows[yEvenRowsRunner])*(y - yEvenRows[yEvenRowsRunner]);
var radius = (20 * 20);
if(radius >= circle){
yPos = (2 * yEvenRowsRunner) +2; //This is just for nicer output
return [yPos, xEvenRowsRunner];
}
}
}
return null;
}
So this is the complete code and like I said, it works fine as long as you don't use the scrollbars. I really appreciate your help - this whole thing drives me nuts.
I've experienced something like this before; I eventually figured it out by using something similar to what you had attempted; I replaced .x and .y with .pageX and .pageY
if (e.pageX || e.pageY) {
x = e.pageX;
y = e.pageY;
}
As far as I am aware, this is because .x and .y do not grab the coordinates relative to the element, but rather relative to the body; in other words, they do not account for scrolling, while pageX and pageY do.
Test case with .x and .y
Test case with .pageX and .pageY
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With