我覺得CCS3的transform中的學問很深,可以出不少面試題了,之前的文章談到過perspective屬性的位置問題,我們今天看看rotate的順序,首先看看下面兩個CSS3的keyframe動畫:
兩個動畫的起始狀態和結束狀態都是是一摸一樣的(其實就是原始位置),不同的只不過是rotate和rotateX的順序。但是動畫效果卻有驚人的差別。


CSS代碼如下:
@-webkit-keyframes raceFlag0{
0%{
-webkit-transform:rotate(-720deg) rotateX(0deg) ;
-webkit-transform-origin:100% 0%;
}
100%{
-webkit-transform:rotate(0deg) rotateX(-360deg) ;
-webkit-transform-origin:100% 0%;
}
}
@-webkit-keyframes raceFlag1{
0% {
-webkit-transform: rotateX(0deg) rotate(-720deg);
-webkit-transform-origin:100% 0%;
}
100% {
-webkit-transform: rotateX(-360deg) rotate(0deg);
-webkit-transform-origin:100% 0%;
}
}
我看了mozilla的網站介紹,裡面沒有提到關於順序的問題。於是我做了以下實驗。
將兩個同樣的元素的style分別設置為:
-webkit-transform: rotateX(-135deg) rotate(-270deg);
-webkit-transform-origin: 100% 0%;
-webkit-transform: rotate(-270deg) rotateX(-135deg);
-webkit-transform-origin: 100% 0%;
結果是不相同的。如下圖:

是不是-webkit-transform-origin設置的原因呢?我們將該屬性刪除:

我們將問題旋轉的角度簡化為45度和90度,為了讓rotateX的效果明顯現一些,我們增加perspective屬性。兩個CSS分別是:
-webkit-transform: perspective(200px) rotateX(45deg) rotate(90deg);
-webkit-transform: perspective(200px) rotate(90deg) rotateX(45deg)

這樣我們就能發現一些規律了。就是rotate旋轉的不是圖像,(也不是寂寞)而是坐標系。具體來說,就是X軸也被旋轉了。rotateX旋轉的也是坐標系。
我們在圖上添加坐標系大家就明白了。注意右面的圖的坐標系順時針旋轉了90度。

我們再看一個個例子:
-webkit-transform: perspective(200px) rotateX(45deg) rotateY(10deg);
-webkit-transform: perspective(200px) rotateY(20deg) rotateX(45deg);

結論:rotate、rotateX、rotateY、rotateZ都是旋轉坐標系。rotateX時,Y軸和Z軸的位置會變。rotateY時,X軸和Z軸的位置會變。rotate和rotateZ時,X軸和Y軸的位置會變。
我們使用rotate時要注意順序,特別是動畫的時候。
進一步的結論:用過canvas中transform的同學可能會知道,在canvas中進行transform時,變形的對象是canvas本身。看來在CSS3的transform中也是一樣的道理。比如我想將圖片旋轉90度,浏覽器的邏輯是,將頁面旋轉-90度,然後渲染圖片,之後再將頁面旋轉90度。這樣就實現了旋轉圖片的效果。
因此在CSS3的tranform屬性中,perspective、rotate、translate等屬性並不是代表對象的最終狀態,而是浏覽器渲染對象的“指令隊列”。浏覽器會依次執行這些“指令”。
這樣也就可以解釋為什麼perspective為什麼要放在transform的第一位了。
PS:以上結論是基於邏輯推理得來,本人沒有看過這部分的浏覽器源代碼,請看過的同學指正。