检查鼠标光标是否在带坐标的数组范围内

Check if mouse cursor is within range of array with coordinates

本文关键字:坐标 数组 范围内 鼠标 光标 是否 检查      更新时间:2024-01-31

我目前正在使用坐标数组在画布上绘制一系列点。

var points =  [[102, 267], [254, 163], [343, 318], [522, 112], [610, 163], [681, 112]];
var canvas = document.getElementById('graph');
var c = canvas.getContext('2d');
function getMousePos(canvas, evt) {
  var rect = canvas.getBoundingClientRect();
  return {
    x: evt.clientX - rect.left,
    y: evt.clientY - rect.top
  };
}
function drawPoints(){
  for (i = 0; i < points.length; i++) {
    c.beginPath(); 
    c.arc(points[i][0], points[i][1], 5, 0, 2 * Math.PI, true);
    c.fillStyle = "black";
    c.fill();
  }
}
drawPoints();

我正试图编写一个函数来识别这些点,并在鼠标悬停在画布上时对它们进行标记。

canvas.addEventListener('mousemove', function(evt) {
  var mousePos = getMousePos(canvas, evt);
  var currMouseX = mousePos.x;
  var currMouseY = mousePos.y;
  for (i = 0; i < points.length; i++){
    if ((points[i][0] >= currMouseX-4 && points[i][0] <= currMouseX+4) && (points[i][1] >= currMouseY-4 && points[i][1] <= currMouseY+4)) {
            console.log('in range of '+points[i]);
      c.beginPath(); 
      c.arc(points[i][0], points[i][1], 8, 0, 2 * Math.PI, true);
      c.fillStyle = "red";
      c.fill();
    }
  }
});

我遇到的问题是,当鼠标光标离开点的范围时,我想删除标记。

如果我在末尾设置了一个简单的else语句,那么循环只适用于数组中的最后一点,因为for循环的其余部分仍在执行。我需要检查点是否被击中,停止for循环,检查鼠标是否离开了点范围,如果是,清除画布并重新绘制点。

也许循环不是处理这一问题的最佳方式,也许针/干草堆的方法会更好,但我不知道在嵌套数组中搜索范围而不是单个值时如何实现这一点。

FIDDLE

您基本上需要一个循环来一直重新绘制画布:

setInterval(drawPoints, 1000 / 30); // redraw at 30 fps

然后你必须清除绘图中的画布点数:

function drawPoints(){
   c.clearRect(0, 0, canvas.width, canvas.height);
  for (i = 0; i < points.length; i++) {
    c.beginPath(); 
    c.arc(points[i][0], points[i][1], 5, 0, 2 * Math.PI, true);
    c.fillStyle = "black";
    c.fill();
  }
}

这导致了一个新的问题,只有当你移动鼠标时,点才会变成红色。这就是您应该将points从数组更改为对象数组的地方:

points = [{x: 123, y: 234, hovered: false}];

以及提款点:

function drawPoints(){
   c.clearRect(0, 0, canvas.width, canvas.height);
  for (i = 0; i < points.length; i++) {
    c.beginPath(); 
    c.arc(points[i].x, points[i].y, 5, 0, 2 * Math.PI, true);
    c.fillStyle = "black";
    if (points[i].hovered) {
      c.fillStyle = 'red';
    }
    c.fill();
  }
}

最后更改移动功能以切换hovered标志。我把那件工作留给你。

我添加了一个变量,用布尔值存储该点是否命中。我添加了一个变量来存储被击中点的索引。

var checkHit = true;
var saveIndex = "";

然后我写了另一个if语句,检查checkHit变量,如果它是false,我检查鼠标光标是否仍在范围内,是否不再在范围内。我重新绘制画布并重置变量。

  if(!checkHit){
    if ((points[saveIndex][0] >= currMouseX-4 && points[saveIndex][0] <= currMouseX+4) && (points[saveIndex][1] >= currMouseY-4 && points[saveIndex][1] <= currMouseY+4)) {
        console.log('point stil in range');
    }
    else {
        c.clearRect(0, 0, canvas.width, canvas.height);
        drawPoints();
      checkHit = true;
            saveIndex = "";
      console.log('Redraw');
    }
  }

FIDDLE

如果有人知道一种资源密集度较低的方法,比如大海捞针的方法,我愿意接受建议/改进。