天天看點

《HTML5 Canvas遊戲開發實戰》——3.1 變形

預設情況下,一個畫布的坐标空間會使用畫布的左上角 (0,0) 作為原點,x 值向右增加,y 值向下增加。這個坐标空間中的機關通常會被轉換為像素,然後,可通過轉換坐标空間在繪圖過程中實作移動、縮放或旋轉等操作。這些操作是通過 translate()、scale() 和 rotate()等方法來實作的,它們會對畫布的變換矩陣産生影響。

3.1.1 放大與縮小

我們用scale函數來實作圖形的放大和縮小。

其函數原型如下:

其中,第一個參數x表示在x軸進行縮放,即水準縮放,第二個參數 y表示在y軸上進行縮放,即在豎直方向上進行縮放。

具體實作方法如代碼清單3-1所示。

代碼清單 3-1

運作後的效果如圖3-1所示。

下面解釋一下代碼清單3-1的代碼。首先,以頁面上的坐标(10,10)為起點開始畫了一個寬150、高100的黑色矩形,如下所示:

《HTML5 Canvas遊戲開發實戰》——3.1 變形

然後,沿着x軸和y軸方向将其值放大3倍,并用同樣的代碼重新畫一個灰色的矩形,如下所示:

從運作效果圖可以看到,雖然用了同樣的代碼,但是第二次畫的灰色矩形被放大了3倍,并且起始坐标值也一起被放大了3倍。

上述代碼清單3-1實作了放大功能,那麼現在來看看縮小功能如何實作,如代碼清單3-2所示。

代碼清單 3-2

運作後的效果如圖3-2所示。

《HTML5 Canvas遊戲開發實戰》——3.1 變形

在代碼清單3-2中,同樣先畫出了一個黑色矩形,然後沿着x軸和y軸方向上分别将其值縮小到了0.5倍,并用同樣的代碼重新畫了一個灰色的矩形。

從運作效果圖可以看到,雖然用了同樣的代碼,但是第二次畫的灰色矩形被縮小為原來的0.5倍了,并且起始坐标值也一起縮小了0.5倍。

另外還需要了解的是,使用scale函數時,如果将參數設定為負數,還可以使圖形翻轉,比如代碼清單3-3就實作了豎直方向的翻轉。

代碼清單 3-3

運作效果如圖3-3所示。

《HTML5 Canvas遊戲開發實戰》——3.1 變形

3.1.2 平移

使用translate函數可以實作對圖形進行平移的功能。

其中,第一個參數x表示在x軸進行平移,即在水準方向上平移,第二個參數 y表示在y軸上進行縮放,即在豎直方向上平移。

具體的實作方法如代碼清單3-4所示。

代碼清單 3-4

運作效果如圖3-4所示。

《HTML5 Canvas遊戲開發實戰》——3.1 變形

在代碼清單3-4中的如下代碼表示在水準方向上向右平移50,在豎直方向上向下平移100,圖3-4中灰色矩形是平移之後的效果。

3.1.3 旋轉

利用rotate函數可以實作圖形的旋轉功能。

這裡需要注意的是,傳入rotate裡的參數angle是弧度而不是角度。如果角度為angle,那麼換算為弧度就是angle*math.pi/180,具體實作方法如代碼清單3-5所示。

代碼清單 3-5

運作效果如圖3-5所示。

在圖3-5中灰色矩形是旋轉45度後的圖形,可以看到用rotate來實作旋轉時,是以canvas的起始坐标(0,0)為中心進行旋轉的。如果要想讓圖形以自己為中心旋轉,則需要使用3.1.2節中的translate函數,如代碼清單3-6所示。

《HTML5 Canvas遊戲開發實戰》——3.1 變形

代碼清單 3-6

運作效果如圖3-6所示。

《HTML5 Canvas遊戲開發實戰》——3.1 變形

在代碼清單3-6中,下面的代碼表示先将canvas的起始坐标向右移250,向下移75,即移至所畫矩形的中心處;然後開始旋轉45度;接着再将canvas的起始坐标向左移250,向上移75,即移回到原來位置,這樣就完成了圖形以自己為中心的旋轉。

3.1.4 利用transform矩陣實作多樣化的變形

上面分别講了縮放、平移以及旋轉的實作方法。其實所有這些變形都是可以通過變形矩陣transform來實作的。先來看看transform函數的定義。

transform函數的原型如下:

該函數的各個變量對應以下變換矩陣中相應位置的參數。

a c e

b d f

0 0 1

下面來說明如何使用這個變換矩陣來實作上面的各種變形。

1 . 縮放

假設原始坐标為(x,y),縮放後的坐标為(x1,y1),縮放的倍數分别為a和d,那麼就有下列公式:

是以,我們得到了如下矩陣公式。

這樣就可以用transform (a,0,0,d,0,0)來替換scale(a,d)了,如代碼清單3-7所示。

代碼清單 3-7

運作效果如圖3-7所示。

《HTML5 Canvas遊戲開發實戰》——3.1 變形

可以看到,這裡用代碼清單3-7實作了和代碼清單3-1一樣的功能。

平移

同樣,假設原始坐标為(x,y),平移後的坐标為(x1,y1),在x軸和y軸的平移量分别為e和f,那麼就有下列公式:

是以,我們得到如下矩陣公式。

這樣就可以用transform (1,0,0,1,e,f)來替換translate (e,f)了,如代碼清單3-8所示。

代碼清單 3-8

運作效果如圖3-8所示。

《HTML5 Canvas遊戲開發實戰》——3.1 變形

可以看到,這裡用代碼清單3-8實作了和代碼清單3-4一樣的功能。

3 . 旋轉

旋轉對應的矩陣公式如下。

現在可以用transform (cos , sin , –sin , cos ,0,0)來替換rotate ()了,如代碼清單3-9所示。

代碼清單 3-9

運作效果如圖3-9所示。

可以看到,這裡用代碼清單3-9實作了和代碼清單3-5一樣的功能。

這樣,我們就用transform完成了所有變形。另外,變換矩陣也可以通過settransform函數來實作,settransform的參數與transform一樣,不同的是,settransform函數是先消去之前的transform變換,然後重新進行變換的。為了區分transform和settransform,我們看看下面的例子,如代碼清單3-10所示。

《HTML5 Canvas遊戲開發實戰》——3.1 變形

代碼清單 3-10

運作效果如圖3-10所示。

《HTML5 Canvas遊戲開發實戰》——3.1 變形

在代碼清單3-10中,首先旋轉5度,然後再旋轉10度,是以第二次旋轉相當于旋轉了15度。

下面再看看代碼清單3-11中settransform的使用方法。

代碼清單 3-11

運作效果如圖3-11所示。

可以看到,第二次的旋轉沒有在第一次旋轉的基礎上進行,因為用settransform實作旋轉效果的時候,已經清除了上一個transform,是以隻旋轉了10度。

4 . 傾斜

接着來看一下如何實作圖像的傾斜效果。首先看圖3-12。

《HTML5 Canvas遊戲開發實戰》——3.1 變形

圖中的3個點p0、p1、p2遵循以下矩形公式。

将上面的矩形公式帶入settransform函數中,如代碼清單3-12所示。

代碼清單 3-12

運作效果如圖3-13所示。

上述傾斜效果也可以根據另外3個點來實作,看圖3-14。

《HTML5 Canvas遊戲開發實戰》——3.1 變形

圖中的3個點p1、p2、p3遵循以下矩形公式。

将上面的矩形公式代入settransform函數中,如代碼清單3-13所示。

代碼清單 3-13

運作效果如圖3-15所示。

《HTML5 Canvas遊戲開發實戰》——3.1 變形

5 . 圖檔的扭曲效果

根據以上所介紹的内容,已經可以做到傾斜、旋轉、平移和縮放4種基本變形,如圖3-16所示。

《HTML5 Canvas遊戲開發實戰》——3.1 變形

但是,對于非上述4種基本變形的特殊變形,就無法直接實作了。比如圖3-17中的扭曲變形效果。

這時候,就需要通過多種變形組合來實作。先對圖3-17進行分解,如圖3-18所示。

此時分解出的兩個圖形可分别看作是兩個基本變形的一部分,如圖3-19所示。

《HTML5 Canvas遊戲開發實戰》——3.1 變形
《HTML5 Canvas遊戲開發實戰》——3.1 變形
《HTML5 Canvas遊戲開發實戰》——3.1 變形

這樣一來就簡單了,隻需要實作兩個傾斜的變形,然後利用clip函數将圖檔的一部分繪制出來,就可以完成圖3-17中的效果了,如代碼清單3-14所示。

代碼清單 3-14

運作上面的代碼,就可以得到圖3-17的效果了。

解釋一下代碼清單3-14。首先看一下左半邊圖形的繪制。

上面這段代碼是以(80,0)、(320,40)和(0,200) 3個點為頂點繪制一個三角形,然後利用clip函數将這個三角形作為繪圖的可視區域。

上面的代碼是以剛才的三角形的3個頂點來進行傾斜變形的,這個變形的原理已經在代碼清單3-12中講過了。

上面的代碼是繪制圖檔,因為繪圖的可視區域隻是一個三角形,是以繪制完的圖檔隻有一部分。

右半邊圖形的繪制思路和左半邊是一樣的。同時,兩次繪圖都加上了save()函數和restore()函數,這是為了讓兩次變形和繪圖互不幹涉。

繼續閱讀