CSS動畫學習指南:原理與例項

段昕理發表於2015-09-25

譯者注:這篇文章比較古老了,大概成文於2011年。放在當今急速變化的web前端世界中似乎有些不合時宜。不過究其所寫的內容-CSS動畫的原理,則萬變不離其宗,理解動畫的基本原理非常重要,裡面提到的12條基礎動畫原則,對建立高質量的動畫效果有著極好的指導意義。當時支援CSS動畫屬性的瀏覽器很少,如今幾乎所有主流瀏覽器基本都支援了(別跟我提IE哦)。文章中的程式碼示例和我們今天寫的CSS3動畫基本是一致,放在現在的瀏覽器跑也沒有相容性問題。

現如今 Firefox 和 基於Webkit引擎的瀏覽器都支援CSS動畫了,擇日不如撞日,何不嘗試一下。拋去技術形態,不管是傳統動畫、電腦3D動畫、Flash或CSS,遵循的動畫原理都是相通的。

我們將在文章中初步瞭解CSS動畫,並按照指導原則建立CSS動畫。然後將通過例項,使用傳統動畫原理建立CSS動畫。最後,展示一些真實世界裡的用例。

CSS 動畫屬性

在深入之前,我們先寫點基礎的CSS:

Animation 是CSS的新屬性,允許我們不需要藉助Javascript或Flash就能為HTML元素(如:div、h1 和 span)建立動畫。現在支援這個屬性的瀏覽器有 包含Webkit 引擎的瀏覽器,如:Safari 4+、Safari for iOS (iOS 2+)、Chrome 1+和Firefox 5。 不支援該屬性的瀏覽器則會忽略動畫程式碼,此時要確保你的頁面不完全依賴這個屬性。

由於這個技術相對來說較新,需要新增瀏覽器廠商的字首。到目前為止,每個瀏覽器的語法規則都是一樣,只是用字首區分。下面的程式碼例子中,我們用的是 -webkit 字首語法。

要為元素新增動畫,你只需要將CSS 動畫關聯到該元素就可以了:

首先,我們建立動畫程式碼。這段程式碼可以出現在CSS檔案中的任何位置,只要元素能找到相應動畫的名字(animation-name)就可以了。

還有一種更簡便的方法為元素新增動畫:

這段程式碼做了一定簡化,並沒有把所有屬性值都寫上。如果某些值沒有寫,瀏覽器會回退使用預設值。

這些是最基礎的。下面我們將展示更多的程式碼。

使用傳統動畫原理

在我看來,傳統動畫的鼻祖迪斯尼,早期在著名的圖書《Illusion of Life》裡創立了傳統動畫的12條原則。這些基礎原則可以應用到所有型別動畫,不過你並不需要像動畫專家一樣遵循。我們將這12條原則運用到CSS動畫例項上,把一個基礎動畫轉變成更加可信的視覺幻象。

雖然只是蹦蹦跳跳的小球,但你可以看出兩個版本中的不同世界。

這個例子展示了CSS動畫特性。下面的程式碼中,我們用一些空div元素來展示如何運作;我們都知道這程式碼不夠語義化,但重點在於它將頁面變得生動起來,這在以前的瀏覽器中是絕對做不到的。

擠壓和拉伸

這個彈跳球為壓扁和拉伸做了很好的展示。如果彈球高速下落並撞擊地面,你可以觀察到它被擠扁然後在彈回的過程中被拉伸。

在基本常識層面,這個例子讓我們的動畫有了重量和伸縮的感覺。如果扔一個保齡球,我們不會期待它有任何拉伸,很可能只是會撞壞地面。

可以通過CSS3的屬性 transform 來產生壓扁和拉伸的效果。

這段程式碼會將物體縱向(y軸,上下)的比例改變為原始比例的1.2倍,然後回覆到原始尺寸。

我們還為這個動畫使用了稍微複雜一點的定時器。對於基礎動畫只需要起始(from)和結束(to)就可以了。但你也可以通過白分比的方式為每個時間點設定動畫,就像程式碼所展示的那樣。

擠壓效果已經實現了。現在我們利用轉換(translate)來移動物體。我們可以它將形變放在一起。

轉換屬性允許我們在不改變基礎屬性(如 位置、寬度、高度)的前提下操作物體,這就使其非常適合CSS動畫。這個特別的轉換屬性讓小球在動畫的中間點從地面彈起。

(請注意:要檢視這個動畫,你需要最新版的Firefox、Chrome或Safari。筆者書寫這段文字的時候,Safari瀏覽器提供了最佳視覺體驗。)

(譯者注:現如今主流的瀏覽器都已經能很好的實現動畫效果了)

檢視擠壓和拉伸的效果.

沒錯,小球看起來還是很糙,不過這個小小的調整是讓動畫變得逼真的第一步。

預備

預備在主要動作發生之前增加了懸念或力量感。舉個例子,在你起跳之前腿部的彎曲有助於觀察者預判你下一步會做什麼。在我們的彈球例子中,事前增加一個簡單的影子表示有東西將要從上面掉下。

檢視預備效果.

我們新增了另一個 div 元素代表影子,這樣我們可以單獨的為其設定動畫。

要在這裡增加預期,我們需要讓小球快速掉入場景中。通過適配各百分比的時間點來實現,小球在開始點和第一個動作之間沒有移動。

在動畫的35%的時間點前,小球在場景中的位置沒有發生變化,沒有移動。然後在 35% 到 65%,小球忽然出現在舞臺上,剩下的動畫緊接著跟上。

也可以使用動畫延遲(animation-delay)來實現預備:

舞臺

現在試試把舞臺新增到場景中,將動畫放入環境中。回顧一下迪士尼的電影,如果去掉了奇妙的背景會變成什麼樣?這是魔法的半壁江山。

舞臺也是吸引注意的關鍵元素。與劇院的舞臺一樣,光線總是照射到最重要的區域。舞臺應該加入到視野中。除了彈球,我為彈球的降落新增了一個簡單的背景。這樣看客就知道舞臺的中央會出現動畫,場景也就可以從一片大白雪(白色區域)中脫穎而出了。

逐幀 VS 狀態到狀態

在傳統動畫中,可以選擇如何構成自己的動畫。逐幀意味著需要畫出序列的每一幀。狀態到狀態意味著建立序列的少數關鍵幀,然後填充中間的間隔。填充間隔在被稱作漸變(“in-betweening”或“tweening”),這是製作Flash動畫的術語。

在CSS動畫中,我們通常使用第二種方式,狀態到狀態。就是說,我們將為動作新增關鍵幀,之後瀏覽器將會自動在這些關鍵幀直接做漸變平滑處理。當然,我們同樣也能向逐幀技術學習。瀏覽器只提供有限的動畫效果;有時候,你為達到某種的效果時,必須採用更困難的方式為多種動畫做拼接。

慣性和重疊

和物理世界一樣!慣性和重疊常用在人物的身體移動中,例如人物胳膊的搖擺或頭髮的下落。想象一個人頂著大肚腩快速的轉身:他們的身體先轉過來,然後肚腩迅速跟上。

對我們來說,這意味著當球掉落時需要使其符合物理定律。上面的例子中小球掉落很不自然,就跟沒有受到重力的影響一樣。我們希望小球掉落,然後彈起。不過得講完下一原則才能實現。

慢進慢出

這是與加速或減速有關。想象一個超速的汽車需要停下來。如果它瞬間就停下來,肯定沒人信。我們知道汽車需要時間來減速,所以要先讓汽車剎車並緩慢停止。

還有一個和重力相關的效果。想象兒童盪鞦韆。當他們達到最高點時會減速,當返回到最低點時又會加速。最快的速度出現在弧面的底部。然後上升到相反的方向,如此反覆。

回到我們的例子,調整進和出的速度可以讓小球的運動(最終)更加可信。

當球撞擊地面,碰撞會使起迅速彈回。當抵達最高點,它會減速。這樣看起來小球像是真正的掉落。

在 CSS 中,我們可以控制 animation-timing-function 屬性:

這些屬性包含以下這些值:

  • ease-in 開始時緩慢,然後加速。
  • ease-out 開始時快速,然後減速直到停止。
  • ease-in-out 開始緩慢,一直加速到中段,然後減速直到停止。
  • linear 一直保持勻速。

你還可以使用貝塞爾曲線來建立自定義的緩動速度。

檢視慢進慢出效果

弧線

與遵循物理定律類似,弧線遵循的基本原則叫做“上升的東西必然落下”。弧線在思考物體運動軌跡時非常有用。

這個動畫用 CSS 來實現稍微繁瑣一點。我們想讓小球上下運動的同時往邊上移動。所以,我們讓小球從左邊平滑進入的同時保持彈跳動畫。與其把所有的動作都放到一個動畫中,不如做兩個獨立的動畫更簡單。在這個例子裡,我們將小球用另一個 div 元素包裹,然後單獨新增動畫。

HTML

CSS

這樣,我們通過一個動畫移動小球的側方向(ball-x),另一個動畫控制小球的彈跳(ball-y)。 這個方法唯一不好的地方在於,如果你想做的事情很複雜,最終會讓你陷入一堆缺乏語義的程式碼堆砌之中。

檢視弧線效果

輔助動畫

輔助動畫是讓動畫顯得更加真實的微妙之處。輔助動畫致力於細節。打個比方,如果有一個留著長髮的人行走,主動作是行走,輔助動作是頭髮的擺動,或者也可能是衣服的褶皺隨風變化。

我們的例子和這個非常相似。為了增加小球的更多細節,我們製作小球紋理的輔助動畫。這樣就造成了小球是被扔進來的錯覺。

這次不再為這個動畫新增另一個div元素,我們新增一個 img 影象元素充當小球的紋理。

檢視輔助動畫

定時

這條原則只針對動畫定時。如果動畫的定時控制得越好,就越接近真實世界。

小球的例子完美的闡釋了這個觀點。例子中的小球很輕,設定這個速度合適的。如果是一個保齡球,我們會希望它下落的速度更快。而如果動畫比現在更慢,則看起來像是在太空中打網球。選擇合適的時間點會讓你的動畫看起來更真實。

可以很方便地通過 animation-duration 來調整時長,也可以通過動畫的百分比設定單獨的時長。

誇張

卡通片以誇張或難以置信的物理特性著稱。一個卡通人物可以變形成任何形狀然後在恢復正常。在很多應用場景中,通過誇張來突出,讓動畫富有活力。否則看起來會很平淡。

儘管如此,使用誇張效果時需要謹慎。迪士尼有一個符合現實原則的方法,但稍微推進了一步。想象一個角色朝牆裡跑,它的身體會被壓扁的特別誇張,用來強調碰撞的力量。

我們使用擠壓和拉伸的誇張手法讓小球對地面的撞擊更加明顯。我還為動畫新增了更精緻的搖晃。最後,我們在球的彈跳過程中拉伸小球來突出速度感。

就像之前新增動畫的做法一樣,我們再新增一個 div 元素,這個元素使小球撞擊地面時同時產生搖晃。

這段程式碼看起來比之前複雜了不少。這是簡單的試錯。在找到合適的效果錢需要反覆嘗試。

檢視誇張效果

紮實繪圖及角色魅力

能夠教你就這麼多了……至少在程式碼方面。最後這兩條動畫原則無法通過程式碼來體現。他們是你日後需要完善的技能,使你最終能製作真正迷人的動畫。

當迪士尼開始製作白雪公主的動畫時,他們的動畫師被派回去重新學習寫生和人體結構。這種對細節的關注在影片中可見一斑。這正好說明良好的動畫需要紮實的繪畫功底和聲樂知識。

大多數的CSS動畫和錯綜複雜的數字動畫不大相同,但是基礎原則是一致的。無論是透過正在開啟的門顯示內容,還是正在密封併傳送一封“聯絡我們”的信封,動畫都必須是可信的,不能像機器一樣……除非你製作的就是機器動畫。

每一個動畫角色都有獨特的魅力。就像迪士尼總給我們展示的,任何事物都可以有性格:一個茶壺、一棵樹、甚至是勺子。但在CSS的世界裡,需要考慮整體動畫如何有助於設計,使整體的體驗更令人滿意。我們不想在此製作大眼怪的動畫。

奔跑吧動畫!

CSS的動畫特性非常棒。和每一個CSS新特性一樣,一開始容易被過度使用和錯誤的使用。甚至有點會重蹈Flash複雜動畫頁面覆轍的危險。儘管我有信心Web社群應該不會這麼做。

CSS動畫能讓網站變得有生機。也許我們的小球動畫不夠簡潔,但它向我們展示一種利用CSS讓頁面上任何元素變鮮活的可能。

CSS動畫還可以讓頁面上的元素更容易互動,讓頁面更有意思。結合JavaScript,甚至能成為製作遊戲動畫的另一條路。將上面的12條原則應用在你的動畫中,能使你的網站更有信服力、更誘人、更有趣,從而帶來更好的完整體驗。

譯者推薦:

如果你和我一樣懶,想製作CSS動畫又不想寫複雜的CSS3程式碼,這有兩個非常不錯的CSS3開源動畫庫推薦給你,Animate.cssCSS3 ANIMATION CHEAT SHEET。另外譯者也編寫了一個CSS3動畫製作庫H5Show,讓你輕鬆的建立時下流行的Html5演示動畫。當然想製作出高水準的動畫,理解文章中的12條動畫原則非常重要。

相關文章