Javascript 如果我有多个形状,如何将鼠标悬停在画布中的形状上并更改颜色?
我希望能够将鼠标悬停在不同的矩形上,并使矩形在悬停时改变颜色,我现在所做的工作适用于最后一个矩形,但其他矩形被清除。矩形是使用类/构造函数、数组和循环创建的。代码如下:Javascript 如果我有多个形状,如何将鼠标悬停在画布中的形状上并更改颜色?,javascript,html5-canvas,Javascript,Html5 Canvas,我希望能够将鼠标悬停在不同的矩形上,并使矩形在悬停时改变颜色,我现在所做的工作适用于最后一个矩形,但其他矩形被清除。矩形是使用类/构造函数、数组和循环创建的。代码如下: /*Variables*/ let canvas = document.querySelector('#canvas'), ctx = canvas.getContext('2d'), square; /*Board Class*/ class Board { constructor(startX, s
/*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=document.querySelector(“#canvas”),
ctx=canvas.getContext('2d'),
广场
/*板级*/
班级委员会{
建造商(起点、起点、高度、宽度、角度){
this.startX=startX;
this.startY=startY;
高度=高度;
这个。宽度=宽度;
这个角度=角度;
}
拖板{
让canvasWidth=window.innerWidth*.95,
drawWidth=canvasWidth*this.width,
drawHeight=画布宽度*this.height,
drawStartX=画布宽度*this.startX,
drawStartY=画布宽度*this.startY;
square=新路径2d();
ctx.旋转(此角度*数学PI/180);
square.rect(drawStartX、drawStartY、drawHeight、drawWidth);
ctx.fillStyle='红色';
ctx填充(方形);
}
}
/*用于更改矩形颜色和重绘的事件侦听器*/
canvas.addEventListener('mousemove',函数(事件){
if(ctx.isPointInPath(square、event.offsetX、event.offsetY)){
ctx.fillStyle='白色';
}
否则{
ctx.fillStyle='红色';
}
clearRect(0,0,canvas.width,canvas.height);
ctx填充(方形);
});
/*实例化数组*/
设b=[];
/*循环创建板并推送到阵列*/
for(设i=1;i<11;i++){
b、 推动(新板(.05*i、.25、.04、.03、0));
}
/*当页面加载时,用于循环通过阵列和绘图板的函数*/
函数loadFunctions(){
background.draw();
b、 forEach(功能(板){
板。拖板();
})
}
这是我第一个使用Canvas API的项目,它给我带来了很多麻烦,通常我可以通过class/id来识别形状,如果它是使用常规HTML元素生成的,但是我不确定从这里开始该怎么做
我尝试过在包含线路板信息的数组中循环,但无法使任何内容正常工作。感谢您的帮助
谢谢让我们逐步浏览您的代码,以更好地了解正在发生的事情 当您在画布上移动鼠标时,mousemove侦听器将被触发并执行其关联的回调函数 在这个回调函数中,我们会发现这是第一行:
if (ctx.isPointInPath(square, event.offsetX, event.offsetY))
因此,如果该if语句检查当前鼠标位置是否在正方形内。好吧,最大的问题是:到底是什么正方形
如果我们仔细查看一下您的代码,就会发现它是一个全局变量,它在Board类drawBoard()
函数中获取一些值,如下所示:
square = new Path2D();
square.rect(drawStartX, drawStartY, drawHeight, drawWidth);
显然,它是一个包含其中一个条的矩形的路径2D,但是实际上是哪个
让我们看看这个函数:
for (let i = 0; i < 10; i++) {
b.push(new Board(0.05 * i, 0.25, 0.04, 0.03, 0));
}
在第一个循环中,您用十个Board实例填充数组b,在forEach循环中,您调用每个Board的drawBoard()函数
这一切意味着什么?是的,square将始终保存对该条的引用,该条的drawBoard()函数上次被调用过,它将始终是数组中的最后一块板
总而言之:在mousemove回调中检查的唯一条是始终数组中的最后一条。
因此:
翻译成简单的英语意思是:如果点在正方形的边界内,将fillStyle设置为红色,清除整个屏幕,然后用红色填充一个条
您需要做的是使用阵列中的每个板实例检查鼠标位置。不过这并不难-只要将Path2D设置为Board的类变量,并在整个数组中的回调函数循环中,将鼠标位置与每个Board的.square属性进行比较即可
下面是一个示例(只需单击“运行代码片段”):
let canvas=document.querySelector(“#canvas”),
ctx=canvas.getContext('2d');
设b=[];
班级委员会{
建造商(起点、起点、高度、宽度、角度){
this.startX=startX;
this.startY=startY;
高度=高度;
这个。宽度=宽度;
这个角度=角度;
this.square=新路径2d();
}
拖板{
让canvasWidth=window.innerWidth*0.95,
drawWidth=canvasWidth*this.width,
drawHeight=画布宽度*this.height,
drawStartX=画布宽度*this.startX,
drawStartY=画布宽度*this.startY;
ctx.旋转(此角度*数学PI/180);
this.square.rect(drawStartX、drawStartY、drawsheight、drawswidth);
ctx.fillStyle='红色';
ctx.填充(此方形);
}
}
canvas.addEventListener('mousemove',函数(事件){
clearRect(0,0,canvas.width,canvas.height);
让我们做一个正方形;
for(设i=0;i
function loadFunctions() {
b.forEach(function(board) {
board.drawBoard();
})
}
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);