寫法:transform:matrix(a,b,c,d,e,f)
在矩陣中:
結合坐標軸計算結果位:
偏移(translate)
利用矩陣實現transform:translate(30px,30px);
等同於transform:matrix(1,0,0,1,30,30)
現在,我們根據這個矩陣偏移元素的中心點,假設是(0, 0)
,即x=0
, y=0
。
於是,變換后的x
坐標就是ax+cy+e = 1*0+0*0+30 =30
, y
坐標就是bx+dy+f = 0*0+1*0+30 =30
.
於是,中心點坐標從(0, 0)
變成了→(30, 30)
。對照上面有個(30, 30)
的白點圖,好好想象下,原來(0,0)
的位置,移到了白點的(30, 30)
處,
實際上transform: matrix(1, 0, 0, 1, 30, 30);
就等同於transform: translate(30px, 30px);
. 注意:translate
, rotate
等方法都是需要單位的,而matrix
方法e, f
參數的單位可以省略。
這里只需要關心后面兩個參數就可以了,前面4個參數在偏移上是不需要考慮的。
旋轉(rotate)
利用矩陣實現transform:rotate(α); //將元素旋轉α度
等同於transform:matrix(cosα,sinα,-sinα,cosα,0,0)
結合矩陣公式,就有:
x'=cosα*x-sinα*y+0=cosα*x-sinα*y
y'=sinα*x+cosα*y+0=sinα*x+cosα*y
結合三角函數是可以推算出來的,
假設有一個點A(x,y),偏移之前與原點之間連線的角度是β,偏移角度是α,偏移之后的點位A'(x',y')。
A點與原點之間的長度不會變,設r,那么r就等於√(x²+y²),cosβ=x/√(x²+y²),sinβ=y/√(x²+y²)。
偏移之后:
A'的橫坐標就為x'=r*cos(α+β)=r*(cosα*cosβ-sinα*sinβ),將上面的r、cosβ和sinβ代入化簡就可以得到x'=cosα*x-sinα*y;
A'的縱坐標就為y'=r*sin(α+β)=r*(sinα*cosβ+cosα*sinβ),將上面的r、cosβ和sinβ代入化簡就可以得到y'=sinα*x+cosα*y;
進而獲得矩陣matrix(cosα,sinα,-sinα,cosα,0,0)。
縮放(scale)
利用矩陣實現transform:scale(1,1);
等同於transform:matrix(1,0,0,1,0,0)
縮放后的元素比例與原來一樣,1:1, 而這幾個參數中,有兩個1, 這兩個1就是縮放相關的參數。
其中,第一個縮放x軸,第二個縮放y軸。
用公式就很明白了,假設比例是s,則有matrix(s, 0, 0, s, 0, 0);,於是,套用公式,就有:
x' = ax+cy+e = s*x+0*y+0 = s*x;
y' = bx+dy+f = 0*x+s*y+0 = s*y;
也就是matrix(sx, 0, 0, sy, 0, 0);,等同於scale(sx, sy);
拉伸(skew)
利用矩陣實現transform:skew(θy,θx);
等同於transform:matrix(1,tan(θy),tan(θx),1,0,0)
拉伸也用到了三角函數,不過是tanθ,而且,其至於b, c兩個參數相關,書寫如下(注意y軸傾斜角度在前):
matrix(1,tan(θy),tan(θx),1,0,0)
套用矩陣公式計算結果為:
x' = x+y*tan(θx)+0 = x+y*tan(θx)
y' = x*tan(θy)+y+0 = x*tan(θy)+y
對應於skew(θx + "deg",θy+ "deg")這種寫法。
其中,θx表示x軸傾斜的角度,θy表示y軸,兩者並無關聯。
鏡像對稱效果
另外還可以利用矩陣實現元素的鏡像對稱效果
transform:((1-k*k) / (1+k*k), 2k / (1 + k*k), 2k / (1 + k*k), (k*k - 1) / (1+k*k), 0, 0));
現已知一是垂直,二是中心點在軸線上,因此有:
(y-y') / (x - x') = -1/ k
(x + x') / 2 * k = (y + y')/2
把x'和y'提出來,就有:
x' = (1-k*k)/(k*k+1) *x + 2k/(k*k+1) *y;
y' = 2k/(k*k+1) *x + (k*k-1)/(k*k+1) *y;
再結合矩陣公式:
x' = ax+cy+e;
y' = bx+dy+f;
就可以得到:
a = (1-k*k)/(k*k+1);
b = 2k/(k*k+1);
c = 2k/(k*k+1);
d = (k*k-1)/(k*k+1);