CSS 動畫指南: 原理和實戰


簡介:無論動畫以何種技術載體呈現,無論是傳統的手繪動畫,還是電腦生成的3D動畫,也無論是用Flash還是CSS, 動畫的基本原理和設計準則都未曾變過的。 在這篇文章中,我們會先解釋CSS動畫的基本概念,並且介紹使用CSS創建動畫的要點。我們以一個例子貫穿始終,利用傳統動畫的準則來逐步構建這個動畫。


作者: Tom Waterhouse

原文連接:http://coding.smashingmagazine.com/2011/09/14/the-guide-to-css-animation-principles-and-examples/#more-105335

譯者: feijia  ([email protected])

(譯者注:本文章中的示例頁面需要翻牆,並推薦使用最新的FF,Chrome等查看)

下篇已經發表:

CSS 動畫指南: 原理和實戰(二)


Firefox和Webkit系列的瀏覽器都已經支持CSS 動畫,是時候動手學習這個新的技術了。 不管動畫以何種技術載體呈現,無論是傳統的手繪動畫,還是電腦生成的3D動畫,也無論是使用Flash技術還是CSS3, 製作動畫的基本原理和設計準則都未曾改變。 在這篇文章中,我們會先解釋CSS動畫的基本概念,並且介紹使用CSS創建動畫的要點。我們將以一個網球下落的例子貫穿始終,利用傳統動畫的準則來逐步構建這個CSS動畫。最後我們會看一些真實世界裏的CSS動畫用法。 




CSS 動畫屬性


在開始前,我們需要了解CSS 動畫的基礎知識。 動畫是一種新的CSS 特性,它可以在不借助JavaScript和Flash的情況下使絕大多數HTML元素動起來(例如div,h1,或者Span等等) 。 現在它已經被Webkit家族的瀏覽器(包括Safari 4+, Safari for iOS(iOS2+),Chrome1+ ) 以及Firefox 5 所支持。不支持這些屬性的瀏覽器則會直接忽略它們,所以使用它們時最好確定你的頁面不會完全依賴這些動畫屬性(譯者:或者你可以使用一些代碼來檢查用戶的瀏覽器是否支持css動畫特性 https://developer.mozilla.org/en/CSS/CSS_animations/Detecting_CSS_animation_support)

目前這一屬性還比較新,所以各家瀏覽器廠商在自己支持的屬性前都加上了前綴 如-moz- (firefox), -webkit- (Safari 和Chrome)在本文的示例代碼中爲簡潔起見,我們只使用-webkit- 前綴。

CSS動畫的聲明就是將一段描述動畫的樣式附加到目標元素上,

  1. /* 這是一段動畫代碼*/  
  2. @-webkit-keyframes example {  
  3.    from { transform: scale(2.0); }  
  4.    to   { transform: scale(1.0); }  
  5. }  
  6.   
  7. /* 這是動畫即將應用的目標元素 */  
  8. div {  
  9.    -webkit-animation-name: example;  
  10.    -webkit-animation-duration: 1s;  
  11.    -webkit-animation-timing-function: ease; /* ease is the default */  
  12.    -webkit-animation-delay: 1s;             /* 0 is the default */  
  13.    -webkit-animation-iteration-count: 2;    /* 1 is the default */  
  14.    -webkit-animation-direction: alternate;  /* normal is the default */  
  15. }  

這段代碼中,第一部分是描述動畫的樣式,名字叫“example",它可以出現在樣式表中的任何位置,或前或後。在描述元素的類中可以使用animation-name 屬性來指定要使用哪個動畫效果。

跟其他的樣式寫法類似的,上面例子中的幾個動畫屬性都可以簡寫成如下格式: 


  1. div {  
  2. -webkit-animation: example 1s ease 1s 2 alternate;  
  3. }  

甚至你也可以把所有的值都省略掉,這時瀏覽器會直接使用默認值。 好了,這些就是基本概念了,應該挺簡單的吧?

傳統動畫的基本準則

迪士尼 - 傳動動畫的鼻祖和大師- 很早就提出了製作動畫的12條準則,並出版了著作:The Illusion of life 來闡述這些準則。 這些基本的準則可以應用到所有的動畫中去,實際上你不需要是個動畫專家也可以學着遵循這些準則。 我們會試着遵循這12條“動畫軍規”,並使用CSS來實現更逼真可信的動畫效果。 


擠壓與拉伸(Squash and Stretch)



如果物體在運動過程中它本身的形體不發生任何變化,那會顯得的非常僵硬。上圖演示是一個誇張的彈跳的網球的草圖。當網球從高處落下並撞擊地面時,你會看到球被壓扁了,而後它再次離地彈起時,又被拉長了。 

球被壓扁和拉伸的過程能夠讓人感覺到網球的彈性,想象一下如果是一個又重又硬的保齡球掉落下來,肯定不會有這樣的效果, 那肯定要把地板砸出個窟窿。
實現上面草圖中網球球落地壓扁再拉伸的效果,我們只要應用CSS3中的transform屬性就能實現:

  1. @-webkit-keyframes example {  
  2.    0% { -webkit-transform: scaleY(1.0); }  
  3.    50% { -webkit-transform: scaleY(1.2); }  
  4.    100% { -webkit-transform: scaleY(1.0); }  
  5. }  

上述代碼會在動畫的不同階段把頁面對象按照縱向(y軸) 拉伸1.2倍再變回原樣。

這段代碼中我們使用了百分比的方式來指定了變形在動畫過程中發生具體時間(也叫關鍵幀)。對於簡單的動畫,你可以直接使用from和to來指定開始和結束的動畫狀態。使用百分比,則可以更加精細的控制動畫播放的關鍵過程。 

接下來我們可以使用translate 屬性來讓物體動起來。我們可以把transform和translate合併使用:

  1. 50% {  
  2. -webkit-transform: translateY(-300px) scaleY(1.2);  
  3. }  

使用translate屬性可以在不改變對象其他屬性(例如位置,高度或寬度)的前提下操縱對象的位置,因此該屬性常用於CSS動畫製作。上述例子代碼,指定了球在動畫播放中點(50%)處的樣子,使它看起來像是正在反彈離開地面。 


注意:要看到我們的例子運行時的效果,你需要使用最新的FF,Chrome或Safari, 在本文寫作時,Safari提供了最好的動畫體驗)

查看示例

好吧,我得承認到目前爲止,這個動畫還是挺垃圾的。但是我們已經向“逼真”這個目標邁進了第一步!

預期(Aniticipation)


預期,就是在人物出場或動作開始前的先兆,它可以增加懸念。例如,當一個人屈腿下蹲,就會讓觀衆聯想到他馬上將要起跳了。在我們的掉落小球的動畫裏,如果我們在球出現之前,加上一個球的陰影,那麼無疑是在爲觀衆構造了一個懸念:馬上要有一個球掉下來了!

查看示例

我們使用了一個新的DIV元素來表示陰影,這樣我們就可以在動畫中分別控制陰影和小球。 爲了製造這種球即將下落的懸念,我們故意在動畫開始時增加一點延時,讓小球不是立即掉下來。 只要稍稍調整一下我們動畫設置的百分比的位置即可:

  1. @-webkit-keyframes example {  
  2.    0% { -webkit-transform: translateY(-300px) scaleY(1.2); }  
  3.    35% { -webkit-transform: translateY(-300px) scaleY(1.2); } /* 和開始時同樣的位置,即讓球等待一會兒再下落 0% */  
  4.    65% { -webkit-transform: translateY(0px) scaleY(1.2); }    /* 當動畫播放到65%時,球再開始下落 */  
  5.    67% { -webkit-transform: translateY(10px) scaleY(0.8); }  
  6.    85% { -webkit-transform: translateY(-100px) scaleY(1.2); }  
  7.    100% { -webkit-transform: translateY(0px); }  
  8. }  


在動畫35%的關鍵幀設置中,球的位置沒有變化,而到65%時,球才完全落地。 除了使用這種方法,你還可以用 animate-delay屬性來設置動畫延遲以達到增加懸念的效果

  1. div {  
  2. -webkit-animation-delay: 1s;  
  3. }  

舞臺佈局(Staging)

迪士尼動畫電影裏絢麗多彩的背景是表現人物的重要手段!因此我們也需要爲我們的動畫創造一個舞臺。 


舞臺同時也是幫助動畫觀衆集中注意力的方法,就像在一個劇院中舞臺上的聚光燈,會牽引觀衆的視線。 在我們的小球動畫中,我已經加入了一個簡單的背景,這個背景使得觀衆能夠知道動畫即將發生在頁面的中央。

順序動畫和關鍵幀填充(Straight-Ahead vs. Pose to Pose)

傳統動畫中,有兩種構建動畫的手段。第一種是順序動畫,即從動畫的第一幀開始繪製按照時間順序一幀一幀的完成整個動畫。第二種方法稱爲"Pose to Pose", 直譯爲從姿勢到姿勢。即先描繪出動畫過程中若干關鍵幀的內容,然後再去填充關鍵幀之間的部分從而逐步完成整個動畫。 填充關鍵幀之間內容的過程稱爲”in-betweening,” or “tweening,” 如果你製作過Flash動畫,應該對這些術語不會陌生。 

對CSS動畫而言,我們一般使用關鍵幀填充的方式來完成動畫。我們先描述動畫過程中的關鍵幀,而後瀏覽器會自動幫我們完成填充。 不過,有時候我們也需要藉助順序動畫的方法來達到精細控制動畫效果的目的,瀏覽器能夠自動實現的效果總是有限的。

動作跟隨和重疊(Follow-Through and Overlapping)

動作跟隨的本質是物理學,要讓動畫逼真就得讓其中的物體和人物的行爲符合物理定律。動作跟隨和動作重疊常常會用在人物動畫中,尤其是肢體的運動,例如當人物把手臂或長髮放下時,手臂或頭髮會在放下後繼續前後搖擺一陣。再設想一下一個有啤酒肚的人物(比如史萊克)快速轉身時的情形: 他的身體會先轉過來,而他突出的肚子則會比身體轉動的要慢一些。


對我們的例子而言,就是要讓球下落時更符合物理定律。而我們之前展示的動畫的小球下落時還不夠自然。我們希望看到球可以自由落體式的下落然後再彈起來。 不過,且讓我們繼續看下一條軍規。 

慢進慢出 (Slow  in and Slow Out)

這條規則講得是物體的運動都是漸變的,加速和減速都需要過程。設想一輛高速行駛的汽車需要停下,如果畫面中的汽車突然停下,那肯定讓觀衆覺得不真實。大家都知道汽車停下來會經過減速的過程。因此要做到逼真,就必須模擬汽車先剎車減速,並最終慢慢停下的過程。 

這條規則和重力的效果也有關係。設想一個正在盪鞦韆的小孩子。當他從低盪到最高點時,他在逐漸減速,由高處再蕩回來的過程又是逐漸加速的過程,他的將在鞦韆的最低點達到最快的速度。 然後他再此經歷減速過程蕩向反方向的高點。

  1. <img src="http://hi.csdn.net/attachment/201110/10/0_13182499848iN3.gif" alt="" />  

把這一準則應用到我們的例子中,通過調整小球進入畫面和彈出畫面的速度,我們可以讓觀衆感到更加逼真的效果:當小球落到地面,並反彈起來的過程中,反彈的越接近高點它的速度就越慢。


在css中我們可以使用animation-timing-function 屬性來配置動畫隨時間變化的速率:

  1. -webkit-animation-timing-function: ease-out;  

這一屬性有4個可選值:

ease-in :開始時慢,並逐漸加速
ease-out: 開始時快,並逐漸減速停下
ease-in-out: 開始慢並加速,到中間時最快,然後又逐漸減速並停下
linear :勻速播放

你還可以使用bezier-curve 函數來創建自己的速率函數(easing speed)

查看示例


弧形運行(Arc)


和跟隨準則一樣,弧度準則也是基於對基本物理定律的觀察:”彈起來的物體最終總會落下“, 考慮物體運行軌跡時,恰當運用弧線。

設想我們把小球從畫面的左側擲向舞臺。 逼真的動畫應該能夠模擬出它沿着弧線(拋物線)落下,並彈起,再次沿弧線落下的過程。


使用CSS製作這樣一個動畫需要一些更加精細的控制。我們需要同時控制小球在縱向和橫向兩個方向上的運行。 因此我們實際上需要讓小球一面平滑的自左向右運動,再結合上之前我們已經製作出的自由下落的動畫。與其用一個複雜的動畫來描述這兩個方向的運動,我們可以直接使用2個動畫來實現,更加簡單。爲了達到這一目的,我們需要在我們的小球之外再添加一個div併爲它單獨配置動畫效果(橫向運動)

HTML 代碼:

  1. <div class="ball-arc">  
  2.    <div class="ball"></div>  
  3. </div>  

CSS代碼:

  1. .ball-arc {  
  2. -webkit-animation: ball-x 2.5s cubic-bezier(0, 0, 0.35, 1);  
  3. }  
  4.    /* cubic-bezier 函數的使用是用來調節動畫運行的速度,這裏我們使球慢慢減速*/  
  5.   
  6. @-webkit-keyframes ball-x {  
  7.    0% { -webkit-transform: translateX(-275px); }  
  8.    100% { -webkit-transform: translateX(0px); }  
  9. }  

上述代碼可以看到,我們新加了一個動畫ball-x 它作用在外層div上,負責小球的橫向運動,而ball-y則作用在內層div上負責縱向運動。 

當然,這樣將動作拆分爲橫向和縱向的寫法有它的缺點,當你真的要創作一些非常複雜的動畫時,這些代碼在語義上比較難以理解。 
查看示例



簡介:無論動畫以何種技術載體呈現,無論是傳統的手繪動畫,還是電腦生成的3D動畫,也無論是用Flash還是CSS, 動畫的基本原理和設計準則都未曾變過的。 在這篇文章中,我們會先解釋CSS動畫的基本概念,並且介紹使用CSS創建動畫的要點。我們以一個例子貫穿始終,利用傳統動畫的準則來逐步構建這個動畫。

接上篇

CSS 動畫指南: 原理和實戰 (一)

作者: Tom Waterhouse

原文連接:http://coding.smashingmagazine.com/2011/09/14/the-guide-to-css-animation-principles-and-examples/#more-105335

譯者: feijia  ([email protected])

(譯者注:本文章中的示例頁面需要翻牆,並推薦使用最新的FF,Chrome等查看)


次要動作(Secondary Action)


要使動畫逼真必須關注細節,除了描繪動畫角色的主要動作外,需要通過對次要動作的描繪進一步增加動畫的真實感。正如諺語所說“惡魔藏在細節裏” 。例如,如果要刻畫一個長髮飄飄的姑娘在走路時,人物行走是主要動作,而次要動作則是她那跟隨步伐搖擺彈跳的長髮,又或是她隨風擺動的裙角。 通過描繪這些細節(次要動作),能夠讓觀衆進一步感到動畫的逼真。

當然在我們的小球動畫中,要比這簡單多了。要給小球的下落增加一些細節,我們可以選擇讓小球在運動中旋轉。那會創造一種小球被人投擲到舞臺上的感覺。 

這次我們不用額外添加一個div來實現這一效果,我們可以把這個旋轉的動畫直接應用到用來顯示小球紋理的img元素上

  1. .ball img {  
  2. -webkit-animation: spin 2.5s;  
  3. }  
  4.   
  5. @-webkit-keyframes spin {  
  6.    0% { -webkit-transform: rotate(-180deg); }  
  7.    100% { -webkit-transform: rotate(360deg); }  
  8. }  

查看示例


恰當的節奏(Timing )


這一點很好理解,動畫中的物體的運動的速度,節奏,直接關係到他們看起來是不是逼真。  我們的小球動畫就是一個生動的例子。 我們目前設定的小球運動的節奏使它看起來比較符合一個質量很輕的網球被拋擲的速度,試想如果我們是在擲一個沉重的保齡球,那麼球下落的一定會比較快。 (譯者:作者原話,糾結於“兩個鐵球同時落地“的同學,我想他的意思是,如果是一個彈性很小的保齡球,它落地後再反彈的高度會短很多)同樣,如果我們讓動畫再慢一些,那同樣會讓它看起來不真實,好似是在太空中打網球了。  

通過調整animation-duration屬性,你可以調整動畫運行的整體時間從而調整動畫運動的節奏,同樣你也可以通過設置百分比的方法來進行微調。 


誇張(Exaggeration)


雖然前面我們說了種種通過模擬物理規律來讓動畫逼真的方法,但是卡通形象當然也不必處處遵循物理規律,恰到好處的誇張可以增加效果。 比如卡通形象可以變形成任何形狀,並最後再變回來。誇張的效果可以使一個動作看起來不那麼平淡,也可以起到強調的作用。

掌握何時使用誇張的火候很有技巧,迪斯尼動畫有一條規則說:在動畫中大部分時候儘量模擬真實的基礎上再並稍稍使它超出一點。好像一個動畫人物跑向一堵牆,他的身體會被擠壓到牆上(當然現實世界不會發生這樣的情形),這種擠壓就是那部分微微誇張的效果。 

我們使用了誇張這一技巧(擠壓和拉伸)來強調球在落地時的效果。我還額外添加了一個微小的顫動效果。最後,我們還加入了球在彈起後加入了拉伸效果來表達它的速度感。

向前幾次一樣,爲了加入顫動,我又加了一個新的div,它將會隨着球落地而抖動。示例代碼如下: 

  1. @-webkit-keyframes wobble {  
  2.   
  3. 0%, 24%, 54%, 74%, 86%, 96%, 100% {  
  4.    -webkit-transform: scaleX(1.0);  
  5. /* 在這些位置,球將會回到正常形狀 */  
  6. }  
  7.   
  8. 25%, 55%, 75% {  
  9.    -webkit-transform: scaleX(1.3) scaleY(0.8) translateY(10px);  
  10. /* 球落地的位置:壓縮效果(寬度增加,高度變小) */  
  11. }  
  12.   
  13. 30%, 60%, 80% {  
  14.    -webkit-transform: scaleX(0.8) scaleY(1.2);  
  15. /* 球落地後的幾個收縮的點 */  
  16. }  
  17.   
  18. 75%, 87% {  
  19.    -webkit-transform: scaleX(1.2);  
  20. /* Subtler squash for the last few bounces */  
  21. }  
  22.   
  23. 97% -webkit-transform: scaleX(1.1);  
  24. /* Even subtler squash for last bounce */  
  25. }  
  26.   
  27. }  
代碼看起來有些複雜,不過不用擔心,通過不斷調整直到你覺得達到了你設想的效果。 

查看示例

紮實的繪畫和人物的魅力(Solid Drawing and Appeal)

我能教你的就這麼多了,至少沒有更多的示例代碼了。最後兩條準則沒辦法CSS代碼演示。 可它們是你必須掌握的使動畫臻於完美的技巧。 

當迪斯尼在製作白雪公主動畫時,它把動畫師們派回重新去上繪畫課,重新理解人類的動作。這種對細節的關注直接提現在它的作品中,優秀的動畫必須有紮實的繪畫功底,以及對你所描繪事物的細緻理解(也許是一個網球,也許是一個人物)

雖然大多數CSS動畫可能不會像一個人物動畫那麼複雜,不過這一原則仍然有效。無論是模擬一扇打開的門,還是製作一個用於”聯繫我們“圖表的打開信封的小動畫,都應當儘量逼真。

每個人物的魅力(Appeal) 都是獨一無二的。迪斯尼的成功經驗告訴我們,任何事物都可以有自己的性格:哪怕是一個茶壺,一棵樹,或是一把調羹。使用CSS的創造網頁動畫,我們也應該考慮這一動畫如何幫助提升頁面整體設計和體驗的作用

開始行動吧!


動畫是項了不起的CSS3新特性。就像其他CSS的新功能,人們很有可能會誤用甚至濫用它,我們也許會重新看到過去那種Flash風格的花哨頁面。不過我相信今天的Web開發者們應該不會重蹈覆轍。 

CSS動畫可以讓網站生動起來,我們的彈跳的網球球的示例代碼也許不是最好的例子,但是它演示了要在頁面中加入一個逼真的CSS動畫的必要步驟。

有了CSS動畫,你可以給你的頁面元素加入許多互動性(而且是在不用Flash前提下!),配合JavaScript,它甚至可以用來製作網頁遊戲。 通過應用本文所介紹的12條準則,你可以爲你的網站製作出更加逼真可信的動畫,從而提升網站的整體用戶體驗。 

CSS動畫工具


許多工具可以幫助你製作CSS動畫。

Sencha Animator

Adobe Edge

Tumult(mac only)

真實的CSS動畫案例


看看真實應用中的CSS動畫會讓你對它所能實現的效果有更深的影響。 

CSS Spider-man animation by Anthony Calzadilla 

CSS Tricks (animated typography person),by Mircea Piturca 

Walking man,by Andrew Hoyer 

Learning CSS3: Useful References and Guidelines, on Smashing Magazine
Mastering CSS Principles: A Comprehensive Guide, on Smashing Magazine

========================================


譯者補充, 下面的代碼可以檢查用戶瀏覽器是否支持CSS 動畫


  1. var animation = false,  
  2.     animationstring = 'animation',  
  3.     keyframeprefix = '',  
  4.     domPrefixes = 'Webkit Moz O ms Khtml'.split(' '),  
  5.     pfx  = '';  
  6.   
  7. if( elm.style.animationName ) { animation = true; }      
  8.   
  9. if( animation === false ) {  
  10.   for( var i = 0; i < domPrefixes.length; i++ ) {  
  11.     if( elm.style[ domPrefixes[i] + 'AnimationName' ] !== undefined ) {  
  12.       pfx = domPrefixes[ i ];  
  13.       animationstring = pfx + 'Animation';  
  14.       keyframeprefix = '-' + pfx.toLowerCase() + '-';  
  15.       animation = true;  
  16.       break;  
  17.     }  
  18.   }  
  19. }  


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