canvas画布中的元素响应鼠标交互
canvas画布中可以拥有很多绘制的元素,掌握这些元素响应鼠标的动作交互很有意义,是画布深入开发的必备基础。本帖以画布中的矩形为例,初探画布上的元素响应鼠标动作交互的实现机制,意在举一反三。矩形是最简单的,尤其是在判断指针是否经过它时。
预想是,画布上绘制的小矩形图像,能够发现鼠标经过它,并作出响应动作。响应方式我们尽量简化:鼠标指针变为手型、自身颜色发生变化。
准备工作:在页面上布局画布。CSS和HTML代码如下:
<style>
#canv { margin: auto; display: block; position: relative; border: 1px solid; }
</style>
<canvas id="canv"></canvas>
开始用JS脚本去实现预设功能。先声明相关变量:
let ctx = canv.getContext('2d'), //画笔
w = canv.width = 740, //画布宽度
h = canv.height = 460, //画布高度
box = { x: 10, y: 10, width: 60, height: 40, color: 'olive' }; //矩形实体化对象
给 box 对象添加一个绘制函数,方便反复调用:
box.draw = function() {
ctx.fillStyle = this.color; //填充颜色
ctx.fillRect(this.x, this.y, this.width, this.height); //画矩形
}
然后运行一次上述函数(也可以稍后一点再运行),让矩形在打开页面时在画布上出现:
box.draw();
接着是重点问题,写一个函数判断鼠标在画布上移动时是否经过上述矩形,函数依然属于 box 对象的一个方法:
box.isBox = function(x,y) {
return (this.x <= x && this.x + this.width >= x && this.y <= y && this.y + this.height >= y);
}
上面的函数需要两个参数,x和y,这两个参数指向鼠标指针移动时的实时xy坐标值,然后拿这个坐标值分别与矩形的xy坐标以及xy坐标+宽、高的和进行比较,返回如下的比较结果:矩形的X坐标值小于等于x、并且矩形的X坐标值+其宽度大于等于x、并且矩形的Y坐标小于等于y、并且矩形的Y坐标值+其高度等于等于y。这个比较结果如果一齐成立,则鼠标指针在矩形范围里,否则不是。
最后编写监听画布上鼠标移动的函数,它将调用上面的判断鼠标指针是否在矩形之上的函数:
canv.addEventListener('mousemove', function(e) {
let ex = e.offsetX, ey = e.offsetY; //获取鼠标xy坐标并赋值给变量 ex、ey
if (box.isBox(ex,ey)) { //调用判断函数,如果函数返回真,则——
this.style.cursor = 'pointer'; //鼠标指针为手型
box.color = 'red'; //矩形填充色为红色
box.draw(); //重新绘制矩形
} else { //否则——
this.style.cursor = 'default'; //鼠标指针为默认
box.color = 'olive'; //颜色回到初始色
box.draw(); //重新绘制矩形
}
});
这是监听整个画布的鼠标移动事件,或许我们需要一个处理机制,以避免过渡的矩形重绘,作为初探,这里就不整那么复杂的了。
实现了上述响应功能,可扩展的机会也就有了,画布上基于响应机制的更为丰富的功能也就有了实现的可能。
<style>
#canv { margin: auto; display: block; position: relative; border: 1px solid; }
</style>
<canvas id="canv"></canvas>
<script>
let ctx = canv.getContext('2d'),
w = canv.width = 740,
h = canv.height = 460,
box = { x: 10, y: 10, width: 60, height: 40, color: 'olive' };
box.draw = function() {
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y, this.width, this.height);
}
box.draw();
box.isBox = function(x,y) {
return (this.x <= x && this.x + this.width >= x && this.y <= y && this.y + this.height >= y);
}
canv.addEventListener('mousemove', function(e) {
let ex = e.offsetX, ey = e.offsetY;
if (box.isBox(ex,ey)) {
this.style.cursor = 'pointer';
box.color = 'red';
box.draw();
} else {
this.style.cursor = 'default';
box.color = 'olive';
box.draw();
}
});
</script>
二楼代码:
<style>
#canv { margin: auto; display: block; position: relative; border: 1px solid; }
</style>
<canvas id="canv"></canvas>
<script>
let ctx = canv.getContext('2d'),
w = canv.width = 740,
h = canv.height = 460,
box = { x: 10, y: 10, width: 60, height: 40, color: 'olive' };
box.draw = function() {
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y, this.width, this.height);
}
box.draw();
box.isBox = function(x,y) {
return (this.x <= x && this.x + this.width >= x && this.y <= y && this.y + this.height >= y);
}
canv.addEventListener('mousemove', function(e) {
let ex = e.offsetX, ey = e.offsetY;
if (box.isBox(ex,ey)) {
this.style.cursor = 'pointer';
box.color = 'red';
box.draw();
} else {
this.style.cursor = 'default';
box.color = 'olive';
box.draw();
}
});
</script>
这个主要还是那句判断鼠标是否在矩形区域内,通过4个条件的满足,可以知道鼠标是否在,并根据结果,做相应操作。学习了{:4_187:} 这个反应还是挺快的呢,鼠标上去就看到变化发生{:4_173:} 看看黑黑的文字说明似乎懂了,但实际操作肯定不行,感觉必须有系统性学习和实践相结合,小辣椒就等黑黑的教程分享吧{:4_189:}
小辣椒 发表于 2022-8-25 15:08
看看黑黑的文字说明似乎懂了,但实际操作肯定不行,感觉必须有系统性学习和实践相结合,小辣椒就等黑黑的教 ...
这个就是教程 红影 发表于 2022-8-25 14:18
这个主要还是那句判断鼠标是否在矩形区域内,通过4个条件的满足,可以知道鼠标是否在,并根据结果,做相应 ...
理解到位 红影 发表于 2022-8-25 14:18
这个反应还是挺快的呢,鼠标上去就看到变化发生
它和元素的鼠标相似事件的反应能力是一样的 马黑黑 发表于 2022-8-25 19:24
理解到位
计算机的判断真是快呢。 马黑黑 发表于 2022-8-25 19:25
它和元素的鼠标相似事件的反应能力是一样的
是的,非常快。 红影 发表于 2022-8-25 21:04
是的,非常快。
属于正常范围 红影 发表于 2022-8-25 21:04
计算机的判断真是快呢。
瞬间 来学习! 马黑黑 发表于 2022-8-25 22:19
属于正常范围
比人的反应快许多。 马黑黑 发表于 2022-8-25 22:19
瞬间
是啊,那些前一步的判断和后一步的变化,都是瞬间就完成了。 红影 发表于 2022-8-26 19:39
是啊,那些前一步的判断和后一步的变化,都是瞬间就完成了。
这就是计算机,它只计算,没有情绪 红影 发表于 2022-8-26 19:38
比人的反应快许多。
人不能与之相比 马黑黑 发表于 2022-8-26 20:15
这就是计算机,它只计算,没有情绪
而且永不疲倦,也不抱怨{:4_173:} 马黑黑 发表于 2022-8-26 20:15
人不能与之相比
人的大脑逻辑判断可能不如计算机,但生物神经传递比计算机还快,被烫的瞬间我们就会缩手,要让计算机去操控设备动作,肯定没这个快。