如何在Canvas中添加事件的方法示例

2020-04-24 19:27:36易采站长站整理

}

drawArray.push(draw1, draw2)

drawArray.forEach(it => {
it()
})

canvas.addEventListener('click', function (e) {
ctx.clearRect(0, 0, 400, 750)
const canvasInfo = canvas.getBoundingClientRect()
drawArray.forEach(it => {
it()
console.log(ctx.isPointInPath(e.clientX - canvasInfo.left, e.clientY - canvasInfo.top))
})
})

上面的代码我们进行了一个很大的改造,我们将每个Path放入到一个单独的函数当中,并将它们push到一个数组当中。当触发点击事件时,我们清空Canvas,并遍历数组重新绘制,每当绘制一个Path进行一次判断,从而在调用isPointInPath方法时,我们能实时的获取当前的最后一个Path,进而判断出当前点所处的Path当中。

现在我们已经间接的实现了对每个Path的单独事件监听,可是其实现的方式需要一次又一次的重绘,那么有办法不需要重绘就能监听事件吗?

首先我们需要知道一次又一次重绘的原因是因为isPointInPath方法是监听的最后一个Path,不过我们在介绍这个方法的时候,说过其第一个参数是一个Path对象,当我们传递了这个参数后,Path就不再去取最后一个Path而是使用我们传递进去的这个Path,现在我们来个demo来验证其可行性:


const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')

const path1 = new Path2D();
path1.rect(10, 10, 100,100);
ctx.fill(path1)
const path2 = new Path2D();
path2.moveTo(220, 60);
path2.arc(170, 60, 50, 0, 2 * Math.PI);
ctx.stroke(path2)

canvas.addEventListener('click', function (e) {
console.log(ctx.isPointInPath(path1, e.clientX, e.clientY))
console.log(ctx.isPointInPath(path2, e.clientX, e.clientY))
})

如上图所示,我们点击了左边图形,打印true,false;点击右边图形,打印false,true。打印的结果表明是没有问题的,不过由于其兼容性还有待加强,所以目前建议还是使用重绘方式来监听事件。

结语

Canvas的事件监听讲到这里基本就差不多了,原理很简单,大家应该都能掌握。
github地址,欢迎start

附录

自己写的一个demo


const canvas = document.getElementById('canvas')

class rectangular {
constructor (
ctx,
{
top = 0,
left = 0,
width = 30,
height = 50,
background = 'red'
}
) {
this.ctx = ctx
this.top = top
this.left = left
this.width = width
this.height = height
this.background = background
}

painting () {
this.ctx.beginPath()
this.ctx.moveTo(this.left, this.top)