HTML5画布事件处理简介

本文主要介绍HTML5画布的事件处理。这篇文章解释了画布的局限,画布元素绑定事件ispointinpath方法,循环重新粉刷和事件冒泡。





DOM是Web前端领域的一个重要组成部分,不仅在使用DOM HTML元素的使用、图形编程也很重要。例如,SVG图,各种图形插入到页面的DOM节点的形式,这意味着可以使用DOM方法操纵图形。例如,有一个元素,可以直接添加到Click事件$(' # P1')。Click(function(){ hellip;} jQuery )。然而,在HTML5画布的DOM方法不再适用,画布使用另一种机制,既在画布上绘制各种图形,油画作为一个整体,图形本身实际上是油画的一部分,不能单独,所以它不能直接对Javascript图形事件增加。

画布的局限性

在画布上,所有的图形都是在框架上绘制的。呈现方法不输出图形元素作为返回值。js也无法获取已绘制的图形元素:


复制代码代码如下所示:
CVS = document.getelementbyid('mycanvas);
CTX = canvas.getcontext(二维的);
therect = ctx.rect(10, 10, 100,100);
Ctx.stroke();
console.log(therect); / /未定义


这段代码在canvas标签绘制一个矩形,首先你可以看到,矩形的方法绘制的图没有返回值。如果你打开浏览器的开发者工具,你可以看到画布标签不添加任何东西在里面,但画布元素和js当前上下文不显示任何新的图形内容。

因此,前端常用的DOM方法在画布上不适用,例如,单击上面画布中的矩形,然后单击整个画布元素。

到画布元素绑定事件

由于事件只能达到canvas元素的水平,如果我们想进一步确认和识别图点击画布,我们需要添加代码来处理。其基本思想是把画布元素的事件,当事件发生时,检查事件对象的位置,然后检查这图形叠加的位置。例如,一个矩形绘制在上面的例子中,包括X轴和Y轴10-110.as 10-110只要在这个范围内的鼠标点击的范围,你可以点击矩形,你可以手动触发Click事件,矩形需要处理的设想。很简单,但它是一个有点复杂的实现。我们需要考虑的不仅是公关的效率的判断的过程,而且在某些地方某些事件类型的复发。我们需要重新定义画布中的捕获和冒泡机制。

首先要做的是将事件绑定到画布元素,例如,如果画布中的图形必须单击事件,则需要通过画布元素对事件进行代理。


复制代码代码如下所示:
CVS = document.getelementbyid('mycanvas);
Cvs.addEventListener(听到咔哒声,功能(e){

},假);


接下来,你需要确定事件对象的位置,及到Map Control中的事件对象E layery属性表示的坐标在画布的内部坐标。但这个属性,歌剧,不支持,和Safari要删除它,所以做一些兼容的写作:


复制代码代码如下所示:
功能geteventposition(EV){
变量x,y;
如果(ev.layerx | | { ev.layerx = = 0)
x = ev.layerx;
Y = ev.layery;
如果(ev.offsetx | | } { ev.offsetx = = 0) / /歌剧
x = ev.offsetx;
Y = ev.offsety;
}
返回:x,y,y,y;
}
注意:使用上述函数,需要将画布元素设置为绝对值。


现在,通过事件对象的坐标位置,判断画布中的图形,以及覆盖这个坐标的内容。

ispointinpath方法

画布上的ispointinpath方法可以确定当前上下文的图形覆盖一定的协调,如:


复制代码代码如下所示:
CVS = document.getelementbyid('mycanvas);
CTX = canvas.getcontext(二维的);
ctx.rect(10, 10, 100,100);
Ctx.stroke();
Ctx.isPointInPath(50, 50); / /真的
Ctx.isPointInPath(5, 5); / /假

接下来,将添加事件判断以确定是否在矩形上出现单击事件。


复制代码代码如下所示:
Cvs.addEventListener(听到咔哒声,功能(e){
P = geteventposition(E);
如果(ctx.ispointinpath(P.,p.y)){
单击矩形
}
},假);

以上是处理画布事件的基本方法,但仍然有在上面的代码中的一些局限性,因为ispointinpath方法判断路径的当前上下文,所以当画布上有多个图形的绘制,只有在一个图的上下文来确定最后的事件,例如:

复制代码代码如下所示:
CVS = document.getelementbyid('mycanvas);
CTX = canvas.getcontext(二维的);
Ctx.beginPath();
ctx.rect(10, 10, 100,100);
Ctx.stroke();
Ctx.isPointInPath(20, 20); / /真的
Ctx.beginPath();
ctx.rect(110, 110, 100,100);
Ctx.stroke();
ctx.ispointinpath(150, 150); / /真的
Ctx.isPointInPath(20, 20); / /假

从上面的代码中,我们可以看到,ispointinpath方法只能确定当前上下文中的图形的路径,而先前绘制的路径无法追溯。解决这个问题的办法是重新绘制所有的图形时,单击事件发生,用ispointinpath确定事件坐标的图的范围。

环重绘和事件冒泡

为了重新循环,该图形的基本参数被保存在前进。

复制代码代码如下所示:
ARR = {
{:10,y:10,宽度:100,高度:100 },
{:110,y:110,宽度:100,高度:100 }
};

CVS = document.getelementbyid('mycanvas);
CTX = canvas.getcontext(二维的);

拉();

函数绘图(){
ctx.clearrech(0, 0,cvs.width,CVS。高度);
arr.foreach(功能(v){)
Ctx.beginPath();
ctx.rect(v.x,y,v.width,v.height);
Ctx.stroke();
});
}

上面的代码预先保存了两个矩形的基本参数。每次抽签的方法被调用时,基本的参数是循环绘制两个矩形。clearRect方法也用在这里是清晰的帆布当重画。接下来要做的是添加事件代理和使用ispointinpath方法为每个上下文环境时,重绘:


复制代码代码如下所示:
Cvs.addEventListener(听到咔哒声,功能(e){
P = geteventposition(E);
抽签(P);
},假);

当事件发生时,事件对象的坐标被传递给绘图方法:


复制代码代码如下所示:
函数绘制(p){
var = { };
ctx.clearrech(0, 0,cvs.width,CVS。高度);
arr.foreach(功能(V I){
Ctx.beginPath();
ctx.rect(v.x,y,v.width,v.height);
Ctx.stroke();
如果(P ctx.ispointinpath(P.,p.y)){
如果传入的事件/协调ispointinpath确定什么
如果当前环境包含了坐标,那么数组中索引值的当前环境
Who.push(我);
}
});
根据阵列 / /索引值,在ARR阵列找到相应的元素。
归谁;
}

在上面的代码中,在事件绘制方法点击将执行重画,重画和检查过程的每一个人物包括事件的坐标,如果这是真的,当点击图,并且在数组中的索引值的图,数组作为绘制方法的返回值。这种处理机制下,如果有N个数字油画,其中一些是重叠的,和点击事件发生在这个重叠区域发生。然后,在绘制方法的返回数组中会有n个成员。数组的最后一个成员位于画布的顶部,而第一个成员位于底部。我们可以把e.target前成员,而其他成员转移到泡沫的节点。当然,这只是最简单的方式处理,如果你真的想模拟DOM处理,你必须有一个家长-孩子关系的图形。

以上是帆布的事件处理的基本方法,在实践中,如何缓存的图形参数,如何重新循环,以及如何处理事件的泡沫需要根据实际情况采取行动。此外,点击是一个很好的处理事件,比较麻烦的是问号,这些事件和mouseout MouseMove,因为鼠标在画布元素,经常发生的是MouseMove事件,所以如果你想给另一组图形鼠标悬停或mouseout,还需要记录鼠标线,设置导入图形的状态。由于处理步骤的复杂性,必须注意性能问题。