Get the location of the rectangle cursor inside the canvas

I have a canvas inside which I have a board / grid. When the user selects their mouse over the intersection of the grid, I want it to show where their game pace will go. This worked great when the board was the exact size of the canvas. I made it smaller by x for the whole round.

So, as you can see in the figure below, green shows the canvas, and the grid - the board. I placed my cursor in the lowest right corner of the green color to show when it fires. The only one that works great is average, because no matter how big the board I make, the middle will always be average.

Any simple fix will only be to make an area with a mouseover event, the size of the board instead of the canvas, but the event listener is on the canvas. My code is below the image

enter image description here

Variables

var canvas = document.getElementById("game-canvas");
var context = canvas.getContext("2d");

var boardSize = 13;
var border = canvas.width / 20;
var boardWidth = canvas.width - (border * 2);
var boardHeight = canvas.height - (border * 2);

var cellWidth = boardWidth / (boardSize - 1);
var cellHeight = boardHeight / (boardSize - 1);

var lastX;
var lastY;

Mouse Event:

canvas.addEventListener('mousemove', function(evt) 
{
    var position = getGridPoint(evt);

    if ((position.x != lastX) || (position.y != lastY))
    {
        placeStone((position.x * cellWidth) + border, (position.y * cellWidth) + border, 'rgba(0, 0, 0, 0.2)');         
    }

    lastX = position.x;
    lastY = position.y;     
});

Gets a point on the grid and converts it to a number 0 - 13 (in this case)

function getGridPoint(evt)
{
    var rect = canvas.getBoundingClientRect();

    var x = Math.round((evt.clientX-rect.left)/(rect.right-rect.left)*boardWidth);
    var y = Math.round((evt.clientY-rect.top)/(rect.bottom-rect.top)*boardHeight);

    var roundX = Math.round(x / cellWidth);
    var roundY = Math.round(y / cellHeight);

    return {
      x: roundX,
      y: roundY
    };
}

And finally, draws a piece on the board:

function placeStone(x, y, color)
{
    var radius = cellWidth / 2;

    context.beginPath();
    context.arc(x, y, radius, 0, 2 * Math.PI, false);
    context.fillStyle = color;  
    context.fill();
    context.lineWidth = 5;
}

I left a couple of bits, like the way the grid is updated, so this is not a series of circles following the mouse, etc., so that it is as short as I can, I was hoping it was just a simple asnwer and no one should recreate it, but if you do, I can enable a function that updates the grid and draws everything. Thanks for any advice.

+4
source share
1 answer

// just as an example w,h are width and height
const box = { x : 10, y : 10, w : 100, h : 100 };
// mouse is the mouse coords and relative to the topleft of canvas (0,0);
var mouse.box = {}
mouse.box.x = mouse.x - box.x;
mouse.box.y = mouse.y - box.y;

mouse.box x, y , , .

mouse.box.nx = mouse.box.x / box.w;
mouse.box.ny = mouse.box.y / box.h;

nx, ny 0-1, ;

,

box.gridW = 10; // grid divisions width
box.gridH = 10; // grid divisions height

pos

mouse.box.gx = Math.floor(mouse.box.nx * box.gridW);
mouse.box.gy = Math.floor(mouse.box.ny * box.gridH);

const ctx = canvas.getContext("2d");


const box = { x : 50,y : 10, w : 200, h : 200, gridW : 10, gridH : 10}


function drawGrid(){
    var sx = box.w / box.gridW;
    var sy = box.h / box.gridH;
    var bx = box.x;
    var by = box.y;
    for(var y = 0; y < box.gridH; y ++){
        for(var x = 0; x < box.gridW; x ++){
            ctx.strokeRect(x * sx + bx, y * sx + by,sx,sy);
        }
    }
    if(mouse.box){
      if(mouse.box.nx >= 0  && mouse.box.nx <= 1 &&
      mouse.box.ny >= 0  && mouse.box.ny <= 1){
          ctx.fillRect(mouse.box.gx * sx + bx, mouse.box.gy * sx + by,sx,sy);
      
         }
    }
         
}
const mouse = {};
canvas.addEventListener("mousemove",(e)=>{
    mouse.x = e.pageX;
    mouse.y = e.pageY;
});

function updateMouse(){
    if(!mouse.box){
        mouse.box = {};
    }
    mouse.box.x = mouse.x - box.x;
    mouse.box.y = mouse.y - box.y;
    mouse.box.nx = mouse.box.x / box.w;
    mouse.box.ny = mouse.box.y / box.h;
    mouse.box.gx = Math.floor(mouse.box.nx * box.gridW);
    mouse.box.gy = Math.floor(mouse.box.ny * box.gridH);
    var p = 20;
    ctx.fillText("x : " + mouse.x,box.x+box.w+10,p); p+= 14;
    ctx.fillText("y : " + mouse.y,box.x+box.w+10,p); p+= 20;
    ctx.fillText("Box relative",box.x+box.w+10,p); p+= 14;
    ctx.fillText("x : " + mouse.box.x,box.x+box.w+10,p); p+= 14;
    ctx.fillText("y : " + mouse.box.y,box.x+box.w+10,p); p+= 14;
    ctx.fillText("nx : " + mouse.box.nx,box.x+box.w+10,p); p+= 14;
    ctx.fillText("ny : " + mouse.box.ny,box.x+box.w+10,p); p+= 14;
    ctx.fillText("gx : " + mouse.box.gx,box.x+box.w+10,p); p+= 14;
    ctx.fillText("gy : " + mouse.box.gy,box.x+box.w+10,p); p+= 14;
}

function mainLoop(time){
    if(canvas.width !== innerWidth || canvas.height !== innerHeight){ // resize canvas if window size has changed
        canvas.width = innerWidth;
        canvas.height = innerHeight;
    }
    ctx.setTransform(1,0,0,1,0,0); // set default transform
    ctx.clearRect(0,0,canvas.width,canvas.height); // clear the canvas
    updateMouse();
    drawGrid();
    requestAnimationFrame(mainLoop);
}
requestAnimationFrame(mainLoop);
canvas {
    position : absolute;
    top : 0px;
    left : 0px;
}
<canvas id=canvas><canvas>
Hide result
+1

Source: https://habr.com/ru/post/1678258/


All Articles