第一章 基础知识
第六节 事件处理
HTML5应用程序是以事件来驱动的。可以在HTML元素上注册事件监听器,并编写用于响应这些事件的实现代码。几乎所有基于Canvas的应用程序都会处理鼠标或触摸事件,有些程序则两种事件都会处理,还有许多程序也会处理其他各种类型的事件,比如键盘事件或者拖放事件。
1.6.1 鼠标事件
在canvas中检测鼠标事件是非常简单的:可以在canvas中增加一个事件监听器,当事件发生时,浏览器就会调用这个监听器了。举例来说,要监听“按下鼠标事件”,你可以这样做:
canvas.onmousedown = function (e) {
// React to the mouse down event
};
此外,可以使用更为通用的addEventListener()方法来注册监听器:
canvas.addEventListener('mousedown', function (e){
// React to the mouse down event
});
除了onmousedown之外,也可以使用onmousemove、onmouseup与onmouseout来注册监听器。
使用onmousedown、onmousemove这样的方式来注册监听器,比调用addEventListener()要稍微简单些,不过,如果要向某个鼠标事件注册许多个监听器的话,那么就得使用addEventListener()方法了。
将鼠标坐标转换为Canvas坐标
浏览器通过事件对象传递给监听器的鼠标坐标,是窗口坐标(window coordinate),而不是相对与canvas自身的坐标。
大部分情况下,开发者需要知道的是发生鼠标事件的点相对于canvas的位置,而不是在整个窗口中的位置,所以必须进行坐标转换。举例来说,在图1-14中,canvas上面显示了一幅精灵表(sprite sheet)的图像。精灵表指的是一张包含许多动画图像的图片。在动画的播放过程中,每次都要在精灵表中选取一张图像显示出来,这意味着你必须知道精灵表中每张图像的精确坐标。
图1-14 精灵表坐标查看器
借助图1-14中所示的应用程序,可以通过移动鼠标来观察屏幕中显示的坐标,以此确定精灵表中每张精灵图像的具体位置坐标。当用户移动鼠标时,应用程序会持续地更新精灵表上方的鼠标坐标,同时还会在屏幕上绘制辅助线。
该应用程序向canvas注册了一个mousemove事件监听器,然后,等到浏览器回调这个监听器时,应用程序会将相对与窗口的鼠标坐标转换为canvas坐标。转换工作是通过类似下面这样的windowToCanvas()方法来完成的:
function windowToCanvas(canvas, x, y) {
var bbox = canvas.getBoundingClientRect();
return { x: x - bbox.left * (canvas.width /bbox.width),
y: y - bbox.top * (canvas.height /bbox.height)
};
}
canvas.onmousemove = function (e) {
var loc = windowToCanvas(canvas, e.clientX,e.clientY);
drawBackground();
drawSpritesheet();
drawGuidelines(loc.x, loc.y);
updateReadout(loc.x, loc.y);
};
...
上述windowToCanvas()方法在canvas对象上调用getBoundingClientRect()方法,来获取canvas元素的边界框(bounding box),该边界框的坐标是相对于整个窗口的。然后,windowToCanvas()方法返回了一个对象,其x与y属性分别对应于鼠标在canvas之中的坐标。
请注意,windowToCanvas()方法不只是将canvas边界框的x、y坐标从窗口坐标中减去,而且在canvas元素大小与绘图表面大小不相符时,它还对这两个坐标进行了缩放。请参阅本书1.1.1小节,该小节解释了canvas元素大小与canvas绘图表面大小的区别。
图1-14中所示应用程序的HTML代码列在了程序清单1-5之中,其JavaScript代码列在了程序清单1-6之中。