首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

使用 HTML5 canvas 进行 Web 绘图(4)

使用 HTML5 canvas 进行 Web 绘图(4)

提高可访问性一款优秀的 Web 应用必须要做到的就是提供给用户很好的可访问性,这包括对鼠标,键盘以及快捷键等操作的响应,canvas 画面的本质仍是一个 DOM 节点,因而开发人员可以通过常规的方法来处理响应。这里,与基于 SVG 的绘图不同,由于 SVG 是一种基于 XML 的声明式的绘图方式,因而,SVG 中任何的图形都可以作为一个独立的 DOM 节点去接收并响应特定事件,而 canvas 由于其像素绘图的本质,则只可以在 canvas 元素节点去处理。
图 5 所示示例代码,当鼠标在 canvas 中移动时,鼠标当前相对于 canvas 中的横纵坐标将实时输出到上方提示信息区域;当用户在 canvas 中单击鼠标左键,将在相应位置创建一个蓝色小球,而后用户可以通过键盘上的左 / 右方向键对蓝色小球进行控制,使其进行横向的移动。示例代码如清单 6 所示。
图 5. 清单 6 所示示例展现清单 6. 实现 canvas 对方向键和鼠标点击事件的响应
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<script type="text/javascript">
var g_x,g_y;    // 鼠标当前的坐标
var g_pointx, g_pointy;   // 蓝色小球当前的坐标
    var canvas;
   
function drawCircle(x,y){    // 以鼠标当前位置为原点绘制一个蓝色小球
var ctx = canvas.getContext('2d');
        ctx.clearRect(0,0,300,300);
        ctx.fillStyle = '#00f';
        ctx.beginPath();
        ctx.arc(x,y,20,0,Math.PI*2,true);
        ctx.fill();
            
g_pointx = x;
        g_pointy = y
}
   
    function onMouseMove(evt) {
// 获取鼠标在 canvas 中的坐标位置
if (evt.layerX || evt.layerX == 0) { // FireFox
g_x = evt.layerX;
g_y = evt.layerY;
}
        document.getElementById("xinfo").innerHTML = g_x;
        document.getElementById("yinfo").innerHTML = g_y;
    }

    function onKeyPress(evt) {
var dx = 3;  // 横向平移步长
        var kbinfo = document.getElementById("kbinfo");
        
if (evt.keyCode == 39){   
            kbinfo.innerHTML="right";
if (g_x<300-dx) drawCircle(g_pointx+dx,g_pointy);
document.getElementById("xinfo").innerHTML = g_pointx;
        }else if (evt.keyCode == 37){
kbinfo.innerHTML = "left";
            if (g_x>dx) drawCircle(g_pointx-dx,g_pointy);
document.getElementById("xinfo").innerHTML = g_pointx;
}
}
            
window.onload = function(){
canvas = document.getElementById('canvas');
// 增加 canvas 节点对鼠标单击,移动以及键盘事件的响应函数
canvas.addEventListener('click', function(evt){drawCircle(g_x, g_y);} , false);
canvas.addEventListener('mousemove', onMouseMove, false);
canvas.addEventListener('keypress', onKeyPress, false);
canvas.focus();  // 获得焦点之后,才能够对键盘事件进行捕获
}
</script>




这里我们对鼠标的移动,单击操作进行响应,在实际应用中可以视特定应用的需求,增加对鼠标摁下,松开或双击等更为丰富操作的响应,增强应用的可访问性。
细心的读者可能发现,在通过不断重绘画面以达到动画效果的过程中,我们的重绘方法首先做的事情都是调用 clearRect(x, y, width, height) 方法将原画面清空,这种销毁而后重绘的方式丢失了之前的画面,使得开发人员不得不重绘整幅画面,这在性能上是难以接受的,一种可行的做法是通过多个 canvas 叠加的方式,根据不同 canvas 上的不同刷新频率,分别完成各自的重绘任务。这种多 canvas 技巧,在处理绘图类应用中最为常见的“撤销”操作时也非常有效,所有的绘图都发生在上层 canvas,只有被用户确认的画面,才会被绘制到底层 canvas 上。鉴于本文所讨论技术范围,这里不做过多讲解,有兴趣的读者可以通过本文参考文献所列资源,进行进一步的深入学习。
总结本文对 HTML5 新引入的 canvas 元素在 Web 绘图中所扮演的角色和所发挥的作用做了最基本的介绍,其中包括使用 canvas 完成基本的 Web 绘图,动画和交互任务,虽然 Flash,Silverlight 也都可以完成相同的任务,甚至在性能上更胜一筹,但是作为一种不依赖任何插件的标准 Web 像素级绘图技术,我们有理由相信随着各大浏览器厂商的加入,canvas 将会更加成熟完善,也会有更多基于 canvas 的绘图类应用不断涌现。
返回列表