HTML5 canvas transform與矩陣
首先,我們看一下w3school上的例子:
Javascript語法:context.transform( a , b , c , d , e , f );
定義與用法:畫布上的每個對象都擁有一個當前的變換矩陣。而transform則是用來定義一個新的矩陣,來替換原來的變換矩陣。
六個參數,對應的矩陣就是:
在這里,我說一下變換矩陣要用到的關於矩陣的知識,一個圖形,在畫布上無非是移動,縮小放大,還有旋轉,斜切,等等。
PS告訴我們,無論多復雜的圖形,都是由一個個點組成的,變換矩陣要做的,無非是應用一定的算法,把一個圖形上的一個點,映射到另一個點上。
那么,我們就可以得出以下公式:
根據中間那個矩陣的不同,我們就可以得到不同的變換效果。
矩陣乘法是這樣定義的:假設有兩個矩陣A和B,如果要通過A*B得到C,那么矩陣A的列數必須與矩陣B的行數相同,方才能進行運算。得到的新的矩陣的第 i 行 ,第 j 列的值 就是A的第 i 行 與 B 的第 j 列相對應的值相乘,然后相加的結果。
首先,我們來看看圖形在畫布上的移動。
算法很簡單:
X’ = X + a
Y’ = Y + b
這樣就把點(X,Y)移動到了(X’,Y’)。
對應的變換的矩陣就是
X’ 1 0 a X
Y’ 0 1 b * Y
1 0 0 1 1
X’ = 1*X + 0*Y + a*1;
Y’ = 0*X + 1*Y + b*1;
1 = 0*X + 0*Y + 1*1;
那么,對應的JS代碼就是context.transform(1,0,0,1,a,b);
再看縮小放大,算法也很簡單:
X’ = X*a;
Y’ = Y*b;
Canvas是按照一定的算法來畫圖的,也就是說,Canvas畫出來的圖都是矢量圖,不會因為放大與縮小而失真,那么,Canvas是如何實現放大與縮小的呢?
其實,無非是對X軸,Y軸乘以各相對應的縮放因子,然后進行路徑的描寫,填充。
對應的變換矩陣就是:
X’ a 0 0 X
Y’ 0 b 0 Y
1 0 0 1 1
X’ = 1*X + 0 * Y + 0*1;
Y’ = 0*X + b*Y + 0*1;
1 = 0*X + 0*Y + 1*1;
對應的JS代碼就是 context.transform(a,0,0,b,0,0);
再看看旋轉,算法
通過圖可以看出來,B點是通過把A點旋轉θ度得來的,即
X’ = cos(a +θ) * r
Y’ = sin(a +θ) * r
根據三角函數公式:cos(α+β)=cosαcosβ-sinαsinβ
可得 X’ = r*cosa*cosθ–r* sina * sinθ= X * cosθ – Y * sinθ;
同理可得 Y’ = x*sinθ+y*cosθ;
X’ cosθ -sinθ 0 X
Y’ sinθ cosθ 0 Y
1 0 0 1 1
對應的JS代碼就是 context.transform(Math.cos(θ * Math.PI/180) , Math.sin(θ*Math.PI/180) , - Math.sin(θ*Math.PI/180) , Math.cos(θ * Math.PI/180) , 0 , 0 );
矩陣的好處就是用6個參數就可以表達出不同的算法來,雖然麻煩了點,但這樣做是值得的。
以此類推,斜切也是一樣的,只是算法要復雜一些。
記住,在canvas中先確定坐標系,再畫圖,其實,平移,放大縮小,斜切,旋轉,都是針對坐標系的,應用不同的坐標系,就可以畫出不同的圖形來。