## 第五課時:圖像變換
以下方法用于圖像變換。
* `CanvasRenderingContext2D.rotate()`:圖像旋轉
* `CanvasRenderingContext2D.scale()`:圖像縮放
* `CanvasRenderingContext2D.translate()`:圖像平移
* `CanvasRenderingContext2D.transform()`:通過一個變換矩陣完成圖像變換
* `CanvasRenderingContext2D.setTransform()`:取消前面的圖像變換
### (1)rotate()
`CanvasRenderingContext2D.rotate()`方法用于圖像旋轉。它接受一個弧度值作為參數,表示順時針旋轉的度數。
~~~
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
ctx.rotate(45 * Math.PI / 180);
ctx.fillRect(70, 0, 100, 30);
~~~
上面代碼會顯示一個順時針傾斜45度的矩形。注意,`rotate()`方法必須在`fillRect()`方法之前調用,否則是不起作用的。
旋轉中心點始終是畫布左上角的原點。如果要更改中心點,需要使用`translate()`方法移動畫布。
### (2)scale()
`CanvasRenderingContext2D.scale()`方法用于縮放圖像。它接受兩個參數,分別是`x`軸方向的縮放因子和`y`軸方向的縮放因子。默認情況下,一個單位就是一個像素,縮放因子可以縮放單位,比如縮放因子`0.5`表示將大小縮小為原來的50%,縮放因子`10`表示放大十倍。
~~~
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
ctx.scale(10, 3);
ctx.fillRect(10, 10, 10, 10);
~~~
上面代碼中,原來的矩形是 10 x 10,縮放后展示出來是 100 x 30。
如果縮放因子為1,就表示圖像沒有任何縮放。如果為-1,則表示方向翻轉。`ctx.scale(-1, 1)`為水平翻轉,`ctx.scale(1, -1)`表示垂直翻轉。
~~~
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
ctx.scale(1, -2);
ctx.font = "16px serif";
ctx.fillText('Hello world!', 20, -20);
~~~
上面代碼會顯示一個水平倒轉的、高度放大2倍的`Hello World!`。
注意,負向縮放本質是坐標翻轉,所針對的坐標軸就是畫布左上角原點的坐標軸。
### (3)translate()
`CanvasRenderingContext2D.translate()`方法用于平移圖像。它接受兩個參數,分別是 x 軸和 y 軸移動的距離(單位像素)。
~~~
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
ctx.translate(50, 50);
ctx.fillRect(0, 0, 100, 100);
~~~
### (4)transform()
`CanvasRenderingContext2D.transform()`方法接受一個變換矩陣的六個元素作為參數,完成縮放、旋轉、移動和傾斜等變形。
它的使用格式如下。
~~~
ctx.transform(a, b, c, d, e, f);
/*
a:水平縮放(默認值1,單位倍數)
b:水平傾斜(默認值0,單位弧度)
c:垂直傾斜(默認值0,單位弧度)
d:垂直縮放(默認值1,單位倍數)
e:水平位移(默認值0,單位像素)
f:垂直位移(默認值0,單位像素)
*/
~~~
下面是一個例子。
~~~
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
ctx.transform(2, 0, 0, 1, 50, 50);
ctx.fillRect(0, 0, 100, 100);
~~~
上面代碼中,原始圖形是 100 x 100 的矩形,結果縮放成 200 x 100 的矩形,并且左上角從`(0, 0)`移動到`(50, 50)`。
注意,多個`transform()`方法具有疊加效果。
### (5)setTransform()
`CanvasRenderingContext2D.setTransform()`方法取消前面的圖形變換,將畫布恢復到該方法指定的狀態。該方法的參數與`transform()`方法完全一致。
~~~
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
ctx.translate(50, 50);
ctx.fillRect(0, 0, 100, 100);
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.fillRect(0, 0, 100, 100);
~~~
上面代碼中,第一個`fillRect()`方法繪制的矩形,左上角從`(0, 0)`平移到`(50, 50)`。`setTransform()`方法取消了這個變換(已繪制的圖形不受影響),將畫布恢復到默認狀態(變換矩形`1, 0, 0, 1, 0, 0`),所以第二個矩形的左上角回到`(0, 0)`。
- 第一章:音視頻
- 第一節:概述
- 第二節:媒體元素
- 第三節:視頻元素
- 第四節:音頻元素
- 第四節:事件
- 第二章:高德地圖
- 第三章:Storage 接口
- 第一節:概述
- 第二節:屬性和方法
- 第三節:事件
- 第四章:IndexedDB
- 第一節:概述
- 第二節:基本概念
- 第三節:indexedDB 對象
- 第四節:IDBRequest 對象
- 第五節:IDBDatabase 對象
- 第六節:IDBObjectStore 對象
- 第七節:IDBTransaction 對象
- 第八節:IDBIndex 對象
- 第九節:IDBCursor 對象
- 第十節:IDBKeyRange 對象
- 第十一節:操作流程
- 第五章:Canvas
- 第一節:概述
- 第二節:繪制圖像
- 第一課時:路徑
- 第二課時:線型
- 第三課時:矩形
- 第四課時:弧線
- 第五課時:文本
- 第六課時:漸變色和圖像填充
- 第七課時:陰影
- 第三節:圖像處理
- 第一課時:寫入圖像
- 第二課時:像素讀寫
- 第三課時:保存和恢復
- 第四課時:畫布
- 第五課時:圖像變換
- 第四節:元素方法
- 第一課時:toDataURL()
- 第二課時:toBlob()
- 第五節:使用實例
- 第一課時:動畫效果
- 第二課時:像素處理