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

时间:2016-04-06 08:07:53

标签: javascript arrays canvas

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

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('indexes', type=str, nargs='+')

args = parser.parse_args()
print args.indexes

➜ python test.py a b c d e
['a', 'b', 'c', 'd', 'e']

我尝试编写一个识别这些点的函数,并将其标记为鼠标悬停在画布上。

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(); } } }); 语句,则循环仅适用于数组中的最后一个点,因为for循环的其余部分仍然执行。我需要检查点是否已被击中,停止for循环,检查鼠标是否已离开点范围,如果是,请清除画布并重新绘制点。

也许循环不是处理这个问题的最佳方法,也许针/ haystack aproach可以更好地工作,但我不知道如何在嵌套中搜索范围而不是单个值时如何实现阵列。

FIDDLE

2 个答案:

答案 0 :(得分:2)

你基本上需要一个循环来重绘画布:

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

然后你必须清除drawPoints中的画布:

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

在drawPoints中:

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标志。我把那件作品留给你了。

答案 1 :(得分:0)

我添加了一个变量,用于存储点或者是否使用布尔值。我添加了一个变量,用于存储被击中点的索引。

var checkHit = true;
var saveIndex = "";

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

  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

如果有人知道资源密集程度较低的方法,例如针/干草堆方法,我愿意接受建议/改进。