如何根据鼠标位置填充矩形 canvas 网格单元格?

How to fillRect canvas grid cell depending on mouse position?

我根据鼠标坐标编写了有关网格参数的漂亮代码。

CANVAS GRID DEMO HERE

我想在鼠标位于选定 (imoX/imoY) 单元格之外时清除填充的选定 (imoX/imoY) 单元格。

应该是这样的:

onmouseover[CellNumberX] = fillRect()

onmouseout[CellNumberX] = strokeRect()

有什么解决办法吗? 谢谢

您可以使用此命中测试来查看鼠标是否在矩形上方:

// mx,my == mouse coordinates, r.x,r.y,r.width,r.height == rect definition
var mouseIsInside= mx>r.x && mx<r.x+r.width && my>r.y && my<r.y+r.height;

或者使用这个命中测试来查看鼠标是否在网格单元格上:

// the offsets are the top left coordinates where the grid begins
var cellX = parseInt((mx-gridLeftOffset)/cellWidth);
var cellY = parseInt((my-gridTopOffset)/cellHeight);

示例代码和演示:

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
ctx.lineWidth=3;

function reOffset(){
  var BB=canvas.getBoundingClientRect();
  offsetX=BB.left;
  offsetY=BB.top;        
}
var offsetX,offsetY;
reOffset();
window.onscroll=function(e){ reOffset(); }


// define each rectangle
var rects=[];
rects.push({x:20,y:20,width:50,height:35,fill:'red'});
rects.push({x:100,y:20,width:75,height:100,fill:'blue'});
rects.push({x:200,y:50,width:75,height:50,fill:'green'});

// listen for mousemove events on the canvas
canvas.addEventListener('mousemove',function(e){handleMouseMove(e);});

draw(0,0);

function draw(mx,my){

  // clear the canvas in preparation to redraw all rects
  // in their new hovered or not-hovered state
  ctx.clearRect(0,0,cw,ch);

  // redraw each rect in the rects array
  for(var i=0;i<rects.length;i++){

    var r=rects[i];

    // is the mouse inside this rect?
    if(mx>r.x && mx<r.x+r.width && my>r.y && my<r.y+r.height){
      // it's outside so fill the rect
      ctx.strokeRect(r.x,r.y,r.width,r.height);
    }else{
      // it's inside so stroke the rect
      ctx.fillStyle=r.fill;
      ctx.fillRect(r.x,r.y,r.width,r.height);
      ctx.strokeRect(r.x,r.y,r.width,r.height);
    }
  }
}

function handleMouseMove(e){

  // tell the browser we're handling this event
  e.preventDefault();
  e.stopPropagation();

  // get the mouse position
  mouseX=parseInt(e.clientX-offsetX);
  mouseY=parseInt(e.clientY-offsetY);

  // redraw all the rects
  draw(mouseX,mouseY);

}
body{ background-color: ivory; }
#canvas{border:1px solid red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h4>Hover mouse over rects to remove fill</h4>
<canvas id="canvas" width=300 height=300></canvas>