1 回答
TA贡献1786条经验 获得超11个赞
让我们逐步检查您的代码,以便更好地了解正在发生的情况。
一旦您将鼠标移到画布上,mousemove侦听器就会被触发并执行其关联的回调函数。
在这个回调函数中,我们会发现它是第一行:
if (ctx.isPointInPath(square, event.offsetX, event.offsetY))
所以这个 if 语句检查当前鼠标位置是否在square内部。好吧,最大的问题是:正方形实际上是什么?
如果我们进一步查看您的代码,我们会发现它是一个全局变量,它在 Board类函数中获取一些值drawBoard(),如下所示:
square = new Path2D();
square.rect(drawStartX, drawStartY, drawHeight, drawWidth);
显然它是一个Path2D,保存着其中一个条形的矩形 - 但实际上是哪一个呢?
我们来看看这个函数:
for (let i = 0; i < 10; i++) {
b.push(new Board(0.05 * i, 0.25, 0.04, 0.03, 0));
}
和
function loadFunctions() {
b.forEach(function(board) {
board.drawBoard();
})
}
在第一个循环中,您将使用Board的十个实例填充数组b,并且在 forEach 循环中,您将调用每个 Board 的drawBoard()函数。
这是什么意思呢?是的,square将始终保留对 bar 的引用,该 bar 函数上次被调用 - 它始终是数组中的最后一个 Board。
总结一下:您在 mousemove 回调中检查的唯一栏始终是数组中的最后一个栏。所以:
if (ctx.isPointInPath(square, event.offsetX, event.offsetY)) {
ctx.fillStyle = 'white';
}
else {
ctx.fillStyle = 'red';
}
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fill(square);
翻译成简单的英语意味着:如果该点在正方形的边界内,则将 fillStyle 设置为红色,清除整个屏幕,然后用红色填充一个栏。
您需要做的是检查数组中每个Board 实例的鼠标位置。但这并不难 - 只需将 Path2D 设为 Board 的类变量,并在回调函数内循环遍历整个数组,并将鼠标位置与每个 Board 的 .square属性进行比较。
这是一个示例(只需单击“运行代码片段”):
let canvas = document.querySelector('#canvas'),
ctx = canvas.getContext('2d');
let b = [];
class Board {
constructor(startX, startY, height, width, angle) {
this.startX = startX;
this.startY = startY;
this.height = height;
this.width = width;
this.angle = angle;
this.square = new Path2D();
}
drawBoard() {
let canvasWidth = window.innerWidth * 0.95,
drawWidth = canvasWidth * this.width,
drawHeight = canvasWidth * this.height,
drawStartX = canvasWidth * this.startX,
drawStartY = canvasWidth * this.startY;
ctx.rotate(this.angle * Math.PI / 180);
this.square.rect(drawStartX, drawStartY, drawHeight, drawWidth);
ctx.fillStyle = 'red';
ctx.fill(this.square);
}
}
canvas.addEventListener('mousemove', function(event) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
let currentSquare;
for (let i = 0; i < b.length; i++) {
currentSquare = b[i].square;
if (ctx.isPointInPath(currentSquare, event.offsetX, event.offsetY)) {
ctx.fillStyle = 'white';
} else {
ctx.fillStyle = 'red';
}
ctx.fill(currentSquare);
}
});
for (let i = 0; i < 10; i++) {
b.push(new Board(0.05 * i, 0.25, 0.04, 0.03, 0));
}
function loadFunctions() {
b.forEach(function(board) {
board.drawBoard();
})
}
loadFunctions();
<canvas id="canvas" width=500 height=300></canvas>
添加回答
举报