css變換transform和動畫animation
來自: http://segmentfault.com/a/1190000004392988
Transform
我們在寫網頁的時候是不是大多數時候在操縱二維空間,但是在position絕對定位的時候,我們遇到了z軸,是不是可以理解為開辟了一個新的空間維度呢,但這也只是簡單的層疊,css里有更強大的屬性:Transform 。
從字面上就能看出,Transform 是 "變型 的意思,他的值主要包括
-
旋轉rotate
-
扭曲skew
-
縮放scale
-
移動translate
-
矩陣變形matrix
以rotate為例,
3D Transform 中 rotate 有三種方法,rotateX(angle) X軸旋轉,rotateY(angle) Y軸旋轉,rotateZ(angle) Z軸旋轉。
XYZ表示一個平面以哪個軸為坐標來旋轉,里面的值是他的角度。為了更形象一點,請看這張圖。
從幾何學上來說,面旋轉為體,這雖然還沒有說到3D,但是已經隱約有了3d的概念了。然后就要說到一個很重要的屬性,perspective。
perspective屬性
依然看字面意思,這個屬性是透視的意思。我們都知道近大遠小的道理,包括上面我們的這張旋轉動畫,如果沒有了perspective屬性,那么你看到的就不再是一個矩形的旋轉,而是一個矩形逐漸變窄,然后逐漸變寬,因為他沒有透視。perspective后面的值是一個數字,他有兩種實現方法,
-
使用transform屬性,perspective作為函數值:
transform: perspective(800);
-
或者直接使用 perspective 屬性:
perspective: 800;
perspective可以寫在畫布(父元素)上,也可以直接寫在元素本身上,對于一張畫布只有一個變型體的時候,幾乎沒有差別。但是當一個畫布上 有多個變型體的時候,兩種寫法的差別立即就表現出來了。就像這張圖,黃色的部分,perspective直接寫在色塊上,紫色的部 分,perspective寫在了父容器上,以畫布作為透視元素,所以子元素的形態都是不一樣的。
perspective的值,則是決定3D變形效果的強度的,這個值大致可以理解為遠近。值越大,你離物體就越遠。就像一個離你很遠的正方體(比如魔方)在做旋轉,他的視覺效果就比較弱,但是如果這個魔方在你的眼前旋轉,那么效果就比較強烈。
而這里我們會用到一個新的Transform的參數,translateZ。
前面rotateZ已經讓我們找到了Z軸,translateZ就可以用來處理Z軸的坐標。讓元素在自己的眼前或近或遠。他的值是要參考父元素的perspective值。
比如父元素的perspective值是800,那么子元素translateZ的值越小,就表示子元素離我們越遠,看起來也就越小。當子元素的 translateZ接近800但是小于800的時候,比如790+,那么這個元素會撐滿整個屏幕(注意,會超出瀏覽器),因為這個時候表示這個元素已經 到了你眼前,眼前就是一片小樹葉也是可以遮擋住后面所有東西的。當子元素超過了800,就表示這個元素已經到了我們眼睛后面,我們是看不見自己后腦勺以后 的東西的,元素就會消失不見。
ps:我們上面那三個平面旋轉的圖,大家能看到在Y或者Y軸的旋轉到90度的時候,圖形消失了,這是因為90度的時候平面與我們的視線平行,面是沒有厚度的,所以也會消失不見。當夾角變大之后又會重新出現,這個被成為視覺盲區。
perspective-origin屬性
簡單的了解了透視之后,再來看一個屬性 perspective-origin ,透視原點。這個屬性就很好理解了,就是透視點的位置,如果你會使用flash,那么perspective-origin就相當于flash里面的對齊點,當你做動畫處理的時候,元素會圍繞這個對齊點來旋轉什么的。CSS3里默認perspective-origin是元素的中心。
transform-style屬性
當有了透視,有了變型之后,就該用到transform-style這個屬性了,他有兩個參數,flat與preserve-3d。flat為默認值,表示平面的;后者preserve-3d表示3D透視。
大家可以簡單的理解為這是開啟3D空間的方法 :
transform-style: preserve-3d;
僅僅是開關,這個屬性不會對我們的畫面造成任何影響,除非你用flat。
3D世界里還有一個原理就是,你無法穿過一個物體看到他后面的物體,除非這個物體是透明的,這里我們就用到一個屬性,backface-visibility,當他的值為hidden的時候,就是正常的3D世界。
Animation
現在簡單的幾何原理都有了,我們可以讓平面變3D的過程動態的演示出來了,就是css3的 Animation。在了解Animation之前,我們必須了解另一個特殊的東西,Keyframes。
這里是圖形圖像里的一個基礎概念就是關鍵幀,每一個關鍵幀代表動畫的一個過程節點,Keyframes具有其自己的語法規則,他的命名是 由”@keyframes”開頭,后面緊接著是這個“動畫的名稱”加上一對花括號“{}”,括號中就是一些不同時間段樣式規則,有點像我們css的樣式寫 法一樣。例如:
@-moz-keyframes name{ 0% { -moz-transform:rotateY(0deg) rotateX(0deg) rotateZ(0deg) translateZ(0px); } 25% { -moz-transform:rotateY(90deg) rotateX(0deg) rotateZ(0deg) translateZ(0px); } 50% { -moz-transform:rotateY(180deg) rotateX(0deg) rotateZ(0deg) translateZ(0px); } 75% { -moz-transform:rotateY(90deg) rotateX(0deg) rotateZ(0deg) translateZ(0px); } 100% { -moz-transform:rotateY(0eg) rotateX(0deg) rotateZ(0deg) translateZ(0px); } }
這里,name是動畫的名稱,百分比里邊只要寫你要實現的動畫就行,可以寫位移啊,色值變化啊,透明度變化啊等等。然后我們再看一下Animation的幾個常用屬性:
animation-name:'name';/*動畫屬性名,也就是我們前面keyframes定義的動畫名*/ animation-duration: 2s;/*動畫持續時間*/ animation-timing-function: linear; /* 動畫頻率,有勻速,先快后慢 linear:動畫以勻速運動 ease:默認值,開始慢,中間快,結束慢,不對稱 ease-in:開始慢,后面快 ease-out:開始快,后面慢 ease-in-out:開始慢,中間快,結束慢,對稱(注意與ease的區別) cubic-bezier(n,n,n,n):可以使用cubic-bezier自定義速度,n的取值從0到1 */ animation-delay: 2s;/*動畫延遲時間*/ animation-iteration-count: 1;/*定義循環資料,infinite為無限次*/ animation-direction: alternate;/*定義動畫方式, normal 動畫僅正向播放。 alternate 動畫正向播放奇數次迭代,并反向播放偶數次迭代。在反向播放周期中,與 animation-timing-function 關聯的值也會反轉。*/
Animation的簡化版本transition
搜集資的時候發現還有一個transition過度屬性,據說他可以稱為animation的簡化版本。因為animation屬性比transition屬性多包含keyframes規則顯式控制當前幀的屬性,因而更加靈活。例如:
.contain{ width: 392px; position: relative; bottom: -20px; opacity: 0;} .contain.on{ bottom: 0; opacity: 1; -webkit-transform:translate(-100px,100px); transition:opacity 500ms ease-out 2s,transform 1500ms ease-in-out; -webkit-animation:opacity 500ms ease-out 2s,transform 1500ms ease-in-out; -moz-animation:opacity 500ms ease-out 2s,transform 1500ms ease-in-out; -ms-animation:opacity 500ms ease-out 2s,transform 1500ms ease-in-out; -o-animation:opacity 500ms ease-out 2s,transform 1500ms ease-in-out; } 當符合某種條件時為contain添加.on類,即可有立即x移動-100px,y移動100px,歷時1500ms;延時2s 歷時500ms的“由下往上 由透明變為實體”的動畫效果。注意針對性寫,而不是寫all ease-in 500ms;性能太低 語法: transition: property duration timing-function delay;
但是需要注意的是:火狐瀏覽器對于transition最后一個數值要求很嚴格,如果延時為0時我們往往會忽略后面的S,則火狐上無效果!
transition 遇到的特殊問題:
.aa完成設定動作之后會恢復原樣,換做animation 設置forwards屬性依舊會恢復原樣。
解決方案:將.aa{display:inline-block;}或者設置為display:block;