矩阵变换
在介绍矩阵变换之前,首先要介绍一下变换矩阵,这个矩阵是专门用来实现图形变形的,它与坐标一起配合使用,以达到变形的目的。当图形上下文被创建完毕时,事实上也创建了一个默认的变换矩阵,如果不对这个变换矩阵进行修改,那么接下来绘制的图形将以画布的最左上角的坐标原点绘制图形,绘制出来的图形也经过缩放、变形的处理,但是如果对这个变换矩阵进行修改,那么情况将会是不一样的。
使用图形上下文对象的transform方法修改变换矩阵,该方法的定义如下。
transform(m11, m12, m21, m22, dx, dy)
该方法使用一个新的变换矩阵与当前变换矩阵进行乘法运算,该变换矩阵的形式如下。
其中,m11、m21、m12、m22 4个参数用来修改使用这个方法之后绘制图形时的计算方法,以达到变形目的,dx与dy参数移动坐标原点,dx表示将坐标原点在x轴上向右移动x个单位,dy表示将坐标原点在y轴上向下移动y个单位。默认情况下以像素为单位。
想要了解m11、m21、m12、m22 4个参数是如何修改变形矩阵以达到变形目的的,就需要掌握矩阵乘法的有关知识,这里由于篇幅有限我们不具体讲述关于矩阵乘法的有关知识,下面将通过几个实例来介绍一下矩阵变形的工作原理。
首先,17.5.1节使用坐标变换进行图形变形的技术中所提到的3种方法,实际上都是隐式地修改了变换矩阵,都可以使用transform方法来进行代替。
translate(x,y)
可以使用context.transform(1,0,0,1,x,y)或context.transform(0,1,1,0,x,y)方法进行代替,前面4个参数(1,0,0,1,x,y或者0,1,1,0,x,y)表示不对图形进行缩放操作,将dx设为x表示将坐标原点向右移动x个单位,dy设为y表示将坐标原点向下移动y个单位。
scale(x,y)
可以使用context.transform(x,0,0,y,0,0)或context.transform(0,y,x,0,0,0)方法进行代替,前面4个参数(x,0,0,y,0,0或0,y,x,0,0,0)表示将图形横向扩大x倍,纵向扩大y倍。dx、dy为0表示不移动坐标原点。
rotate(x,y)
替换方法如下。
context.transform(Math.cos(angle*Math.PI/180),
Math.sin(angle*Math.PI/180),
-Math.sin(angle*Math.PI/180),
Math.cos(angle*Math.PI/180),0,0);
或者
context.transform(-Math.sin(angle*Math.PI/180),
Math.cos(angle*Math.PI/180),
Math.cos(angle*Math.PI/180),
Math.sin(angle*Math.PI/180),0,0);
图17.21 transform方法实现的彩虹
其中前面4个参数以三角函数的形式结合起来,共同完成图形按angle角度的顺时针旋转处理,dx、dy为0表示不移动坐标原点。
【例17.17】下面通过实例来看一下transform方法的工作原理。在该实例中,用循环的方法绘制了几个圆弧,圆弧的大小与位置均不变,只是使用了transform方法让坐标原点每次向下移动10个像素,使得绘制出来的圆弧相互重叠,然后对圆弧设置七彩颜色,使这些圆弧的外观达到彩虹的效果。
使用transform方法后,接下来要绘制的图形都会按照移动后的坐标原点与新的变换矩阵相结合的方法进行重置,必要时可以使用setTransform方法将变换矩形进行重置,setTransform方法定义如下。
context.setTransform(m11, m12, m21, m22, dx, dy);
图17.22 使用setTransform方法绘制变形图形
setTransform方法的参数及参数的用法与transform相同,事实上,该方法的作用为将画布上的最左上角重置为坐标原点,当图形上下文创建完毕时将所创建的初始变换矩阵设置为当前变换矩阵,然后使用transform方法。
【例17.18】下面通过实例来了解一下setTransform的具体的使用方法。在该实例中首先创建一个红色边框的长方形,然后将该长方形顺时针旋转45度,绘制出一个新的长方形,并且绘制其边框为绿色,然后将红色长方形扩大2.5倍绘制新的长方形,边框为蓝色,最后在红色长方形右下方绘制同样大小的长方形,边框为灰色。
https://www.bilibili.com/video/BV1qL411u7eEhttps://www.bilibili.com/video/BV1qL411u7eE