## 坐标变换
在Canvas中,变形包括移动、旋转、缩放、变形,跟CSS3中的2D转换类似。
(注意:原有内容不会受变形的影响,变形只是坐标变换,新绘制的图形就是在变换后的坐标轴里绘制的。)
下面我们来逐一的认识。
**一、移动(translate)**
canvas的移动是指移动 canvas 和它的原点到一个不同的位置。
```
translate(x, y)
```
translate 方法接受两个参数。x 是左右偏移量,y 是上下偏移量,如右图所示。
实例:canvas-demo/translate.html:
```
cxt.fillRect(0,0,100,100);
cxt.save();
cxt.translate(60,60);
cxt.fillStyle="red";
cxt.fillRect(0,0,100,100);
cxt.restore();
```
**二、旋转(rotate)**
用于以原点为中心旋转 canvas。
```
rotate(angle)
```
这个方法只接受一个参数:旋转的角度(angle),它是顺时针方向的,以弧度为单位的值。
实例:canvas-demo/tranform-rotate.html:
```
cxt.beginPath();
cxt.moveTo(0,50);
cxt.lineTo(100,50);
cxt.stroke();
cxt.save();
cxt.rotate(Math.PI/12);
cxt.strokeStyle="red";
cxt.beginPath();
cxt.moveTo(0,50);
cxt.lineTo(100,50);
cxt.stroke();
cxt.restore();
```
**三、缩放(scale)**
```
scale(x, y)
```
scale 方法接受两个参数。x,y 分别是横轴和纵轴的缩放因子,它们都必须是正值。值比 1.0 小表示缩小,比 1.0 大则表示放大,值为 1.0 时什么效果都没有。
实例:canvas-demo/scale.html:
```
cxt.fillRect(20,20,50,50);
cxt.save();
cxt.scale(.5,.5);
cxt.fillStyle="red";
cxt.fillRect(20,20,50,50);
```
**四、变形**
区别: transform()方法的行为相对于由 rotate(),scale(), translate(), or transform() 完成的其他变换。例如:如果我们已经将绘图设置为放到两倍,则 transform() 方法会把绘图放大两倍,那么我们的绘图最终将放大四倍。这一点和之前的变换是一样的。 但是setTransform()不会相对于其他变换来发生行为。它的参数也是六个,context.setTransform(a,b,c,d,e,f),与transform()一样。
```
transform(m11, m12, m21, m22, dx, dy)
```
参数:
m11 水平缩放绘图。 默认值1
m12 水平倾斜绘图。 默认值0
m21 垂直倾斜绘图。 默认值0
m22 垂直缩放绘图。 默认值1
dx 水平移动绘图。 默认值0
dy 垂直移动绘图。 默认值0
这个方法必须将当前的变形矩阵乘上下面的矩阵:
```
m11 m21 dx
m12 m22 dy
0 0 1
```
注意:该变换只会影响 transform() 方法调用之后的绘图。
```
setTransform(m11, m12, m21, m22, dx, dy)
```
参数: m11 水平缩放绘图。 默认值1 m12 水平倾斜绘图。 默认值0 m21 垂直倾斜绘图。 默认值0 m22 垂直缩放绘图。 默认值1 dx 水平移动绘图。 默认值0 dy 垂直移动绘图。 默认值0
**五、transform和translate、scale、rotate**
**5.1 translate**
```
cxt.translate(dx,dy)
```
cxt.transform (1,0,0,1,dx,dy)代替cxt.translate(dx,dy)。 也可以使用 cxt.transform(0,1,1,0.dx,dy)代替。
**5.2 scale**
```
cxt.scale(m11, m22):
```
也即是说可以使用 cxt.transform(m11,0,0,m22,0,0)代替cxt.scale(m11,m22); 也可以使用cxt.transform (0,m22,m11,0, 0,0);
**5.3 rotate**
```
rotate(θ)
```
也即是说可以用
- `cxt.transform(Math.cos(θ*Math.PI/180),Math.sin(θ*Math.PI/180)`
- `Math.sin(θ*Math.PI/180),Math.cos(θ*Math.PI/180),0,0)`可以替代`context.rotate(θ)`。
- 也可以使用 cxt.transform(-Math.sin(θ*Math.PI/180),Math.cos(θ*Math.PI/180), Math.cos(θ*Math.PI/180),Math.sin(θ*Math.PI/180), 0,0)替代。