2017-05-31 92 views
4

我有一個畫布,裏面有一個板/網格。當用戶在網格的交叉點上突出顯示他們的鼠標時,我希望它顯示他們的遊戲peice將要去的地方。當電路板是畫布的確切尺寸時,這非常合適。我一直讓它稍微小一點。獲取畫布內的矩形的光標位置

因此,您可以在下面的圖片中看到,綠色顯示畫布,網格是董事會。我將光標放在綠色的右下角以顯示觸發時間。唯一能夠正常工作的是中間一個,因爲不管我做多少板子,中間都是中間的。

任何簡單的解決方法只是使用鼠標懸停事件來創建區域,而不是畫布的板的尺寸,但事件偵聽器位於畫布上。我的代碼是下面的圖像

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

我留下了幾個位出怎麼樣的電網refreshs所以它不是圓的字符串後面你的鼠標之類的東西,保持它短,因爲我可以,即時通訊希望它只是一個簡單的asnwer,沒有人需要重新創建它,但如果你這樣做,我可以包含刷新網格並繪製所有內容的函數。三江源的任何建議

回答

1

要相對的位置到達了一個框mouse.box的x,y

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

負值和大於框的寬度和高度具有鼠標之外的值越大。

更多的方便,你可以得到鼠標正常化POS盒子

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

爲NX中的COORDS,紐約是一個範圍在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>

+0

我想我明白你這意味着,只需將原點(0,0)移至框的原點即可。 - 改變了這個'var x = Math.round((evt.clientX-rect.left) - border /(rect.right-rect。左)* boardWidth);'所以它包括 - 邊界,它似乎工作正常,我有一種感覺我錯過了一些東西,但生病找到它,謝謝:) –