[英]How can I hover over a shape in canvas and change the color if I have multiple shapes?
我希望能夠將鼠標懸停在不同的矩形上,並在懸停時讓矩形改變顏色,我現在對最后一個矩形有效,但其他矩形被清除。 矩形是使用類/構造函數、數組和循環創建的。 代碼如下:
/*Variables*/
let canvas = document.querySelector('#canvas'),
ctx = canvas.getContext('2d'),
square;
/*Board Class*/
class Board {
constructor(startX, startY, height, width, angle) {
this.startX = startX;
this.startY = startY;
this.height = height;
this.width = width;
this.angle = angle;
}
drawBoard() {
let canvasWidth = window.innerWidth * .95,
drawWidth = canvasWidth * this.width,
drawHeight = canvasWidth * this.height,
drawStartX = canvasWidth * this.startX,
drawStartY = canvasWidth * this.startY;
square = new Path2D();
ctx.rotate(this.angle * Math.PI / 180);
square.rect(drawStartX, drawStartY, drawHeight, drawWidth);
ctx.fillStyle = 'red';
ctx.fill(square);
}
}
/*Event Listener for changing rectangle color and redrawing*/
canvas.addEventListener('mousemove', function(event) {
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);
});
/*Instantiate Array*/
let b = [];
/*Loop to create boards and push to array*/
for(let i = 1; i < 11; i++){
b.push(new Board(.05 * i, .25, .04, .03, 0));
}
/*Function to loop through array and draw boards when page loads*/
function loadFunctions(){
background.draw();
b.forEach(function(board){
board.drawBoard();
})
}
這是我使用 Canvas API 的第一個項目,它給我帶來了很多麻煩,通常我可以通過 class/id 識別形狀,如果它是用常規 HTML 元素制作的,但我不知道從哪里開始.. .
我試過遍歷包含電路板信息的數組,但無法獲得任何工作。 任何幫助表示贊賞!
謝謝
讓我們逐步完成您的代碼,以更好地了解正在發生的事情。
只要您將鼠標移到畫布上, 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 的引用,即上次調用 drawBoard() 函數時 - 這將始終是數組中的最后一個 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>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.