對CSS3 transform屬性matrix()矩陣一些學習
1.首先回顧transform屬性的相關知識
先理解網頁上的x,y軸
transform屬性
1.偏移
- transform: translate(x,y) :移動元素位置,x,y為水平和豎直移動的距離,單位是px
- translateX(x) 定義轉換,只是用 X 軸的值。 測試
- translateY(y) 定義轉換,只是用 Y 軸的值。 測試
- translateZ(z)
2.旋轉
- transform: rotate(x deg):2D旋轉x度,正值順時針轉,負值逆
- 3D旋轉
- rotateX()
- rotateY()
- rotateZ()
- 預設旋轉的基點是元素中心點
3.傾斜
- transform: skew(x deg,y deg):2D傾斜,x,y為沿x,y軸傾斜的角度
- skewX()
- skewY()
- skew預設旋轉的基點是中心點
- 當傾斜的角度大於45度時,實際看到的元素是反過來的,無論怎麼傾斜,元素在x,y軸的投影與原始寬高一致,所以元素才會變形
skew(60deg,60deg) 黃框為原始大小
4.縮放
- transform: scale(x,y) :2D縮放,加引數z可3D縮放,x,y,z數值為縮放倍率如1.5
- scaleX(x) 通過設定 X 軸的值來定義縮放
- scaleY(y) 通過設定 Y 軸的值來定義縮放
- scaleZ(z)
transform-origin屬性
設定旋轉的基點
-
transform-origin: x-axis y-axis z-axis;
-
x值可以是left/right,center,%,具體px
-
y值可以是top/bottom,center,%,具體px
-
z值自然為z軸的具體座標
2. transform屬性的matrix()
第一次見到這個矩陣,是在用jq獲取transform屬性的返回值時發現,返回的是一段奇怪的引數,後來多方查閱後才瞭解,matrix()矩陣表示了transform屬性的原理,也就是元素髮生變化的原理實現
寫法如下:
transform: matrix(a,b,c,d,e,f);
a,b,c,d,e,f的六個引數實際上對應的是一個矩陣
而如果要使元素的座標變化,其中是實現原理如下:
x,y是元素的原座標,ax+cy+e對應的是變換後的x軸座標 x’
- 偏移(translate)
顯然,在a,b,c,d值不改變的情況下,改變e,f的值就是改變 x’ ,
y’ 的常數項
所以,若只改變e,f的值,就相當於改變元素的偏移,(e,f)其實就是元素的中心點位置座標
實際上也就是
transform: matrix(a, b, c, d, e, f);
相當於
transform: translate(e px, f px);
- 縮放(scale)
再觀察矩陣的式子,縮放就是改變x,y的係數的倍數
顯然,若改變x係數倍數而不改變y係數,則只改變a的值
同理,改變y則需只改變d的值
所以
transform: matrix(a, 0, 0, d, 0, 0);
相當於
transform: scale(a, d);
- 旋轉(rotate)
旋轉相對複雜些,涉及到三角函式的變換,與a,b,c,d引數有關
transform: matrix(cosθ,sinθ,-sinθ,cosθ,0,0)
矩陣變換實際長這樣
所以
transform: matrix(cosθ,sinθ,-sinθ,cosθ,0,0)
相當於
transform: transform:rotate(θ化為弧度制 deg);
若需要獲取元素的rotate(θ)的旋轉角度θ,則需要利用返回值中的引數值cosθ與sinθ
問題也就轉化為:已知sinθ和cosθ,求θ值。這裡就需要用到反三角函數了,是個數學問題。
- 傾斜(skew)
傾斜也涉及三角函式,不過只改變的是tanθ的值,只與b,c引數有關,方法如下:
transform: matrix(1,tan(θy),tan(θx),1,0,0)
利用矩陣運算後的結果:
x’ = x+ytan(θx)+0 = x+ytan(θx)
y’ = xtan(θy)+y+0 = xtan(θy)+y
所以
transform: matrix(cosθ,sinθ,-sinθ,cosθ,0,0)
相當於
transform: rotate(θ化為弧度制deg);
- matrix()的優點
相比translate、scale、rotate、skew,matrix()可以實現映象對稱,其實原理就是相對於y=tanθ x直線進行翻轉,下面是具體方法(k=θ)
transform: matrix((1-k*k) / (1+k*k), 2k / (1 + k*k), 2k / (1 + k*k), (k*k - 1) / (1+k*k), 0, 0)