HTML5的Canvas中提供了路径旋转、移动、扩大/缩小等变形功能。
在制作动画或绘制复杂的图形时,经常会用到两个变形方法transform()以及rotate()。在实际绘制前执行了这些方法后,实际绘制出来的图形中将显示旋转或变形。
setTransform(m11,m12,m21,m22,dx,dy) | 变形矩阵的指定(清空先前的指定) |
transform(m11,m12,m21,m22,dx,dy) | 变形矩阵的指定(可重复指定) |
rotate(angle) | 旋转 |
scale(x,y) | 扩大/缩小 |
translate(x,y) | 移动/变形 |
setTransform()与transform()的区别是,是否对已经设置的变形矩阵进行清空。transform()方法可重复制定不同效果的变形矩阵,而setTransform()方法被调用后将清空原先设置的变形矩阵。另外,提供旋转或扩大/缩小功能的rotate()方法、scale()方法与translate()方法都支持重叠变形矩阵。
save() | 记录变形矩阵的状态 |
restore() | 恢复变形矩阵的状态 |
context.scale(x,y);
参数x为长度缩放的比例,参数y为宽带缩放的比例
context.translate(x,y);
(x,y)为基点移动后的坐标
简单案例:
移动translate(x,y)放大/缩小scale(x,y)
context.save();//变形的保存
context.restore();//变形的恢复
上述两种方法都是基于同一堆栈(stack)构造,调用save()方法后,将变形结果保存在堆栈顶端,调用restore()方法后,从堆栈顶端取出上次保存的结果用于恢复。
context.rotate(angle);
简单案例:通过移动/旋转等方式,分别绘制三个长方形。结合save()方法、restore()方法,以及rotate()方法。
旋转
上述程序中,首先绘制最初的红色长方形,接着,保存矩阵状态后,移动基点并旋转45度绘制新的绿色长方形。绿色长方形绘制结束后,恢复原先的矩阵状态,为绘制下一个长方形做准备。先移动基点,随后旋转90度,绘制蓝色的长方形。
注释掉第一个ctx.save();和ctx.restore();语句试试会发生哪些不同变化。
context.setTransform(m11,m12,m21,m22,dx,dy);
其中的参数可变换为如下的矩阵
m11 m12 dx
m21 m22 dy
0 0 1
(1)、第1个参数m11
参数m11的默认值为1.0.当此值越大时,以Canvas区域的左侧面为基准,向右延伸坐标空间。相反当值比1.0小时,向左侧收缩坐标空间。m11为0时,实际坐标空间完全消失。但是,当m11的值为比0小的负数时,坐标空间变成以左侧为基准,向左侧延伸。
另外,在Firefox3.6中,当m11或m22的值比0小时,本来的图像将全被隐藏起来,其后当值重新恢复到0以上的数值时,隐藏的图像也不能恢复。
m11分别为0,0.5,1.0,1.5,2.0时,图像:
(2)、第2个参数m12
参数m12的默认值为0.0,当此值变大时,以canvas区域左侧面为基准,坐标空间向右下方向倾斜。相反当此值比0.0小时,以Canvas区域左侧面为基准,坐标空间向右上方向倾斜。
m12分别为-1,-0.5,0,0.5,1时,图像:
(3)、第3个参数m21
参数m21的默认值为0.0,当此值变大时,以canvas区域的上侧面为基准,坐标空间向右下方向倾斜。相反当此值比0.0小时,以Canvas区域的上侧面为基准,坐标空间向左下方向倾斜。
m21分别为-1.0,-0.5,0,0.5,1.0时,图像:
(4)、第4个参数m22
参数m22的默认值为1.0,当此值越大时,以Canvas区域的上侧面为基准,向下延伸坐标空间。相反当值比1.0小时,向上侧收缩坐标空间。m22为0时,实际坐标空间完全消失。但是,当m22的值为比0小的负数时,坐标空间变成以下侧为基准,向上延伸。
当m22的值分别为0,0.5,1.0,1.5,2.0时,图像:
(5)、第5个参数dx
参数dx的默认值为0,当此值越大时,Canvas的坐标空间向右移动。相反当此值变成负数时,坐标空间将向左移动。
当dx的值分别为-200,-100,0.0,100,200时,图像:
(6)、第6个参数dy
参数dy的默认值为0,当此值越大时,Canvas的坐标空间向下移动。相反当此值变成负数时,坐标空间将向上移动。
当dy的值分别为-200,-100,0.0,100,200时,图像:
图标旋转效果(IE8不支持)
详细解释move()函数 :
ctx.setTransform(1,0,0,1,0,0);//初始化变形矩阵
ctx.clearRect(0,0,cw,ch);//清空canvas
首先将变形矩阵恢复成默认值。便于坐标运算。
//计算变形矩阵
var m11=Math.cos(deg*Math.PI/180);
var dx=(cw/2)-(cw*m11/2);
为了让Canvas坐标平面看起来像在立体的旋转,只需要变动m11与dx即可。
在只变动m11的情况下,将以Canvas 区域的左侧面为基准进行左右伸缩。因此,通过使用dx来进行水平调整,使将向左右伸缩后的图像中心始终在Canvas区域的中心位置。
//变形矩阵设置
ctx.setTransform(m11,0,0,1,dx,0);
//将变形后的图像绘制入canvas中
ctx.drawImage(image,0,0);
将计算出来的数值m11和dx,传入到setTransform()方法中,重新设置变形矩阵。然后调用drawImage()方法重新绘制图像即可。