获取画布内矩形的光标位置

时间:2017-05-31 11:55:17

标签: javascript html5 canvas

我有一个画布,里面有一块板/网格。当用户在网格的交叉点上突出显示鼠标时,我希望它显示他们的游戏角色将去哪里。当电路板的尺寸与画布完全相同时,这种方法非常好。我一直把它缩小了x。

因此,如下图所示,绿色显示画布,网格是电路板。我将光标放在绿色的右下角,以显示它何时触发。唯一一个正常工作的是中间的,因为无论我制作多大的板,中间总是中间。

任何简单的修复都只是使用鼠标悬停事件来创建区域,而不是画布而是事件监听器在画布上。我的代码在图片下方

enter image description here

变量:

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;

鼠标悬停在事件上:

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;     
});

获取网格上的点并将其转换为数字0 - 13(在本例中)

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
    };
}

最后在棋盘上画出一块:

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;
}

我离开了几个网格,就像网格刷新一样,所以它不是跟随你的鼠标和东西的一串圆圈,保持它尽可能短,我希望它只是一个简单的asnwer,没有人需要重新创建但是如果你这样做,我可以包括刷新网格和绘制所有内容的功能。谢谢你的任何建议

1 个答案:

答案 0 :(得分:1)

获取相对于方框的位置

// 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

然后获取鼠标的网格位置

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>