日期:2014-05-17 浏览次数:20781 次
?
?
2.2.3 变换
现在我们探讨一下在canvas上绘制图像的另一种方式--使用变换(transformation)。接下来的代码清单显示结果跟上
面是一样的,只是绘制对角线的代码不一样。这个简单示例可能会让你误认为使用变换增加了不必要的复杂性。事实并非
如此,其实变换是实现复杂canvas操作的最好方式。在后面的示例中将会看到,我们使用了大量的变换,而这对熟悉
HTML5 Canvas API的复杂功能是至关重要的。
?
也许了解变换最简单的方法(至少这种方法不涉及大量的数学公式,也不需手足并用地去解释)就是把它当成是介于
开发人员发出的指令和canvas显示结果之间的一个修正层(modification layer)。不管在开发中是否使用变换,
修正层始终都是存在的。
?
修正--在绘制系统中的说法是变换--在应用的时候可以被顺序应用、组合或者随意修改。每个绘制操作的结果显示
在canvas上之前都要经过修正层去做修正。虽然这么做增加了额外的复杂性,但却为绘制系统添加了更为强大的
功能,可以像目前主流图像编辑工具那样支持实时图像处理,所以API中这部分内容的复杂性是必要的。
?
不在代码中调用变换函数并不意味着可以提升canvas的性能。canvas在执行的时候,变换会被呈现引擎
隐式调用,这与开发人员是否直接调用无关。在接触最基本的绘制操作之前,提前了解系统背后的原理至关
重要。
?
关于可重用代码有一条重要的建议:一般绘制都应从原点(坐标系中的0,0点)开始,
应用变换(缩放、平移、旋转等),然后不断修改代码直至达到希望的效果。如图2-4所示。
?
代码清单2-7展示了如何使用最简单变换方法--translate函数。
? |
(点击查看大图)图2-4 基于原点绘制和变换的示意图 |
- <script>?
- ??function?drawDiagonal()?{ ?
- ????var?canvas?=?document.getElementById('diagonal'); ?
- ????var?context?=?canvas.getContext('2d'); ?
- ?
- ????//?保存当前绘图状态 ?
- ????context.save(); ?
- ?
- ????//?向右下方移动绘图上下文 ?
- ????context.translate(70,?140); ?
- ?
- ????//?以原点为起点,绘制与前面相同的线段 ?
- ????context.beginPath(); ?
- ????context.moveTo(0,?0); ?
- ????context.lineTo(70,?-70); ?
- ????context.stroke(); ?
- ?
- ????//?恢复原有的绘图状态 ?
- ????context.restore(); ?
- ??} ?
- ?
- ??window.addEventListener("load",?drawDiagonal,?true); ?
- </script>?
我们详细研究一下上面这段通过平移方式绘制对角线的JavaScript代码。
(1) 首先,通过ID找到并访问canvas对象。(ID是diagonal。)
?
(2) 接着通过调用canvas对象的getContext函数获取上下文对象。
?
(3) 接下来,保存尚未修改的context,这样即使进行了绘制和变换操作,
也可以恢复到初始状态。如果不保存,那么在进行了平移和缩放等操作以后,
其影响会带到后续的操作中,而这不一定是我们所希望的。在变换前保存context状态可以方便以后恢复。
?
(4) 下一步是在context中调用translate函数。通过这个操作,当平移行为发生的时候,
我们提供的变换坐标会被加到结果坐标(对角线)上,结果就是将要绘制的对角线移动到
了新的位置上。不过,对角线呈现在canvas上是在绘制操作结束之后。
?
(5) 应用平移后,就可以使用普通的绘制操作来画对角线了。代码清单中调用了
三个函数来绘制对角线--beginPath、moveTo以及lineTo。绘制的起点是
原点(0,0),而非坐标点(70,140)。
?
(6) 在线条勾画出来之后,可以通过调用context.stroke()函数将其显示在canvas上。
?
(7) 最后,恢复context至原始状态,这样后续的canvas操作就不会被刚才的平移
操作影响了。图2-5显示了用这段代码绘制的对角线。