元素轉換-Transform

所謂元素轉換,其實就是對元素的座標在二維或三維空間上做矩陣換算。根據換算的結果,又分成了多種轉換類型。但無論是哪一種,都不影響元素在頁面上的物理空間,只改變元素的視覺效果。也就是說,比如元素縮放、旋轉都不影響周圍其他元素的佈局。有些人喜歡用平移做元素居中效果,其實非常不妥,因爲元素原來的物理空間還在那裏,控制起來不輕鬆。

另外,轉換屬性(transform)只有一個。也就是說,如果之前做了旋轉(rotate),如果再做平移(translate),旋轉效果就會消失。如果既想平移,又想旋轉,必須使用matrix或matrix3d方法。但也不是不能疊加,只是多個效果需用空格分開,比如:transform:rotateY(90deg) translateZ(50px);

無論是二維還是三維,記住,所有這些轉換基於的是笛卡爾座標左手系(而且是沿X軸翻轉了180度的左手系),而不是右手系。如果你不清楚左手系和右手系,請查度娘。

設置轉換原點

轉換原點在縮放、傾斜和旋轉中很重要,具體參考各轉換。轉換原點默認是元素的中心,即transform-origin: 50% 50% 0。

轉換矩陣

在二維空間中,轉換矩陣是一個3x3矩陣;在三維空間中,是4x4矩陣。下面這個公式左邊的2x2矩陣,就是一個轉換矩陣,因爲是2x2的,所以只能做縮放、旋轉、傾斜,不能做平移。因此,實際上,瀏覽器使用的是3x3或4x4的矩陣。

矩陣右邊(x,y)是原座標,(ax+cy, bx+dy)是轉換後的座標。

轉換公式

CSS 2D transforms

Translating –平移

平移和position:relative效果相似,不影響元素的物理空間位置,隻影響視覺空間位置,也就是說雖然看起來元素已經離開了原來的位置,但它所佔的物理空間依然是原來位置,並且只在原位置上對其他元素有影響。

平移的距離即可以使用像素值,也可使用百分比。如果是百分比,則盒子的寬高(width & height)決定了百分比的最終值,其中,水平位移取決於盒子寬度,垂直位移取決於盒子高度。

transform: translate(50px, 100px);
transform: translateX(50px);
transform: translateY(50%);
transform: translateY(100px);

在不支持的瀏覽器中,使用position:relative,然後通過top和left即可以調整。

Scaling – 縮放

縮放即指放大或縮小,但效果只相當於用放大鏡看,元素所佔的物理空間依然沒有變化。因此,放大或縮小元素,不影響周圍其他元素的佈局。

當然,放大縮小也是有方向的,因爲原點默認是中心點,所以默認是中心向四周放大。如果要修改放大縮小方向,需要修改transform-origin。

如果有一個值爲0,那麼這個元素就看不到了;如果scale只接受了一個參數,表示x和y方向縮放同樣倍數。

transform: scale(2.5);
transform: scale(2, 1);
transform: scaleX(2);
transform-origin: left top;

Skewing – 傾斜

傾斜有向X軸傾斜和向Y軸傾斜,其中向X軸傾斜在視覺上是逆時針扭曲,向Y軸傾斜在視覺上是順時針扭曲。因此,如果X軸和Y軸傾斜角度相同,而正負相反,則等同於旋轉(rotate),旋轉方向由第一個值決定。

傾斜邏輯:一個維度傾斜的時候,另一個維度的大小保持不變。比如,skew(30deg),表示向X軸方向傾斜30度,但元素的縱軸高度保持不變。因此,對於skew(30deg),第一象限空間的變換公式爲x=x+y*tan(30deg)。

transform: skew(30deg);
transform: skew(30deg, 0);
transform: skew(30deg, -30deg);

注意:傾斜沒有3D轉換。

Rotating – 旋轉

二維旋轉其實就是在三維空間上繞Z軸旋轉,旋轉方向爲順時針方向,原點默認是元素的中心點,因爲transform-origin的默認值爲transform-origin:50% 50% 0。如果要把左上角設爲原點,則應該設置transform-origin爲transform-origin: 0 0 0。

transform: rotate(30deg);

CSS 3D transform

以下提到的3D轉換,在IE9都不支持。

Translating -平移

沿X和Y軸的平移是二維就支持的,這裏主要講如何沿Z軸平移。想要看到3D效果的沿Z軸平移效果,首先父元素需要設置perspective,即元素前面離用戶的距離是多少。現在假設perspective爲正值,即perspective>0px。如果translateZ(shift)中,shift小於perspective,則表示元素依然在用戶眼睛正前方,用戶始終可以看到元素。如果shift大於perspective,則表示元素已經已到了用戶的後面,用戶看不到這個元素了。

而且你會發現shift在小於perspective的情況下,如果shift值越大,元素看起來也越大,這符合人眼看由遠及近的物體時所看到的情況。

另外,注意z軸座標和z-index完全是兩碼事,互不影響。

transform: translate3d(50px, 100px, 0);

Scaling - 縮放

3D縮放需要注意的是縮放原點,原點決定了縮放方向,對視覺效果影響很大。

Rotating – 旋轉

同樣,要想看到3D旋轉效果,也需要父元素設置有perspective樣式,否則轉換方法rotate3d()、rotateX、rotateY、rotateZ的效果和在二維空間一樣,而且rotateX和roateY在二維空間是無效的。不過這不妨礙rotate3d和rotateZ可以做XY二維空間換算,比如,rotate3d(0, 0, 1, 10deg)就可以讓元素在二維空間上順時針旋轉10度,同理,rotateZ(10deg)也可以讓元素在二維空間上順時針旋轉10度。

transform: rotate3d(0, 0, 1, 30deg);

注意:ie9不支持rotate3d、rotateX、rotateY、rotateZ方法。

Perspective - 透視

透視距離表示z=0平面和用戶之間的距離,perspective>0表示z=0平面在用戶前面,否則在用戶後面,這時用戶就看不到這個元素了。

<div style="perspective: 50px;">
    <div style="translateZ(20px);">content</div>
</div>

上面這段代碼表示z=0平面離用戶50個像素,而content離z=0平面20個像素,也就是說現在content離用戶只有30個像素。因此,用戶看到的content比正常的要大。另外transform:perspective(50px)+transform-style:preserve-3d效果等同於perspective:50px。

但perspective:50px和transform:perspective(50px)有一個很大的區別,就是perspective屬性的原點是perspective-origin,而transform的原點是tranform-origin。

兼容性

早版本的Firefox、Chrome、Opera或IE,分別使用一下前綴兼容:

-moz-transform: rotate(30deg);
-o-transform: rotate(30deg);
-webkit-transform: rotate(30deg);
-ms-transform: rotate(30deg);
transform: rotate(30deg);

IE

IE的BasicImage濾鏡支持四個旋轉值:0,1, 2, 和 3分別對應0, 90, 180和 270度。

filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);

另外,IE有一個矩陣濾鏡,也可以做到CSS的transform效果,具體參考:https://msdn.microsoft.com/en-us/library/ms533014%28VS.85,loband%29.aspx

如果自己算不來,這裏還有一個工具可以幫助你計算:http://www.useragentman.com/IETransformsTranslator/。注意,用高版本的IE在兼容模式下不一定能看這些效果,需要真實的該版本IE才能看到。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章