## 坐標變換
在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)替代。