是否可以根据边界创建鼠标悬停事件?

Is it possible to create a mouseover event based on boundaries?

我有一个网格覆盖层,其中每个 dividual 盒子的所有角都保存在一个数组数组中(即让 boxes = [[x0,y0,x1,y1,x2,y2, x3,y3],[...]];) 我正在模拟在整个网格上施加的力并将其分解为每个正方形(就像自制的 FEA)。当鼠标悬停在该范围上时,我想尝试显示每个正方形的力。这可能吗?我知道如何使用 HTML 中的 div 来做到这一点,但我不确定如何从数组中提取范围并让程序知道鼠标在该范围内。现在我用鼠标点击显示它们:

///Shows force at clicked coordinates
function getCursorPosition(canvas, event){
    let rect = canvas.getBoundingClientRect()
    let x    = event.clientX - rect.left
    let y    = event.clientY - rect.top
    for(let i = 0; i < plateForces.length; i++){  
        if( plateForces[i][0] < x && x <= plateForces[i][4] && plateForces[i][1] < y && y <= plateForces[i][5] ) {
            // Point is in bounding box 
            context.fillStyle = "black";
            context.font      = "bold 20px Ariel";  
            context.fillText( JSON.stringify(plateForces[i][8].toFixed(1)), x, y);
        }
    }
    console.log(x,y)

}
canvas.addEventListener('mousedown', function(e) { getCursorPosition(canvas, e) });

如有任何帮助或建议,我们将不胜感激。

有几种方法可以解决这个问题。在这个例子中,我使用了一个基本的矩形碰撞检测算法。为了做到这一点,我给了我的鼠标对象一个非常小的宽度和高度。现在我可以检查碰撞了。

从那里我可以将碰撞单元格传递给我调用的函数 pressure(),它会根据我设置的距离为单元格着色。我从中使用了毕达哥拉斯定理。

Math.sqrt(a * a + b * b)

或者在 JS 中你也可以使用 Math.hypot

Math.hypot(dx, dy)

这就是全部,您可以根据与鼠标位置的距离使用不同的颜色。

我不知道你是如何创建网格和单元格的,所以我只是在这里使用了一个循环来创建网格。

let canvas = document.getElementById("canvas");
let ctx = canvas.getContext("2d");
canvas.width = 500;
canvas.height = 500;
let cellSize = 25;
let canvasBounds = canvas.getBoundingClientRect();
let grid = [];
const mouse = {
  x: 10,
  y: 10,
  width: 0.1,
  height: 0.1,
  clicked: false
};
canvas.addEventListener("mousemove", (e) => {
  mouse.x = e.x - canvasBounds.left;
  mouse.y = e.y - canvasBounds.top;
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  drawGrid();
});

class Cell {
  constructor(x, y) {
    this.x = x;
    this.y = y;
    this.width = cellSize;
    this.height = cellSize;
    this.c = "transparent";
    this.center = { x: this.x + this.width / 2, y: this.y + this.height / 2 };
  }
  draw() {
    ctx.strokeStyle = "grey";
    ctx.strokeRect(this.x, this.y, this.width, this.height);
    ctx.fillStyle = this.c;
    ctx.fillRect(this.x, this.y, this.width, this.height);
  }
  collision() {
    if (mouse.x && mouse.y && collision(this, mouse)) {
      pressure(this);
    }
  }
}
function createGrid() {
  for (let y = cellSize; y < canvas.height; y += cellSize) {
    for (let x = 0; x < canvas.width; x += cellSize) {
      grid.push(new Cell(x, y));
    }
  }
}
createGrid();

function drawGrid() {
  for (let i = 0; i < grid.length; i++) {
    grid[i].draw();
    grid[i].collision();
  }
}
drawGrid();

function pressure(cell) {
  for (let i = 0; i < grid.length; i++) {
    if (distance(cell, grid[i]) < 60) {
      cell.c = "red";
      grid[i].c = "orange";
    } else if (distance(cell, grid[i]) > 60 && distance(cell, grid[i]) < 130) {
      grid[i].c = "yellow";
    } else {
      grid[i].c = "transparent";
    }
  }
}

function distance(p1, p2) {
  return Math.hypot(p1.center.x - p2.center.x, p1.center.y - p2.center.y);
}

function collision(first, second) {
  if (
    !(
      first.x > second.x + second.width ||
      first.x + first.width < second.x ||
      first.y > second.y + second.height ||
      first.y + first.height < second.y
    )
  ) {
    return true;
  }
}
<canvas id='canvas'></canvas>