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>
添加回答
舉報
