提前發布於:http://www.alloyteam.com/2012/08/animations-in-canvas/

關於Canvas中動畫的處理和實現
大致會有三種類型:
- 矢量動畫【No Textures】
- 關鍵幀動畫
- 骨骼動畫
這里先分別做一個淺析。都會做一個大致的介紹,這篇文章暫不會涉及深入的技術細節。
【矢量動畫】
顧名思義,這里暫且把不用素材,只用一些矢量的繪制就能達到的動畫效果歸為矢量動畫。矢量動畫,個中有很多很多的例子,比如一些粒子效果啊,矢量線條的特效,或者一些3D的矢量特效等等。
應該可以說矢量的效果是其他效果制作的基礎,而且它能完成一些通過素材達不到的效果,尤其是在處理或者演示一些數學模型的時候。
通常比較簡單,也比較容易出新花樣的是一些粒子特效。我這邊列幾個比較簡單的demo
通常,有了以點為單位的粒子效果,把點連成線,也就能夠完成一些基於線條或者平面的動畫了。比如下面這個例子:
做基於矢量的動畫,在canvas上面可能比較需要注意的地方是一些細節的問題,可能和性能有密切的關系。
- 注意beginPath和closePath的使用,尤其是beginPath,因為他們通常標志這這一次路徑的繪制是否閉合結束。如果沒有beginPath和closePath,瀏覽器將不知道下一次的繪制路徑是否重新開始,那么它只能把上一次沒有閉合的路徑重新繪制一次。如果出現這種情況,在連續繪制幾次之后,由於冗余繪制疊加的原因,會發現性能陡然間極速下降。
- canvas的矢量API是較為消耗性能的,所以盡量減少canvas矢量API的調用,如果是對於相同形狀的矢量圖,有個簡單直接的優化方案,就是將這個需要重復繪制的矢量圖先繪制在一個臨時的canvas上,然后在需要繪制這個矢量圖的地方直接通過drawImage把這個臨時canvas繪制上去即可。
【關鍵幀動畫】
通常實際的應用中,好多動畫還是需要素材的幫助,比如大多數的游戲里,或者一些apps里面。目前很常用的關鍵幀動畫在web上都是利用序列幀圖有序播放來完成的。比如下面這個序列圖
我們按照之前設定好的數據,按順序播放序列圖中的每個部分,連貫起來就會有動畫的效果,這是最基本的邏輯,我們小時候看的動畫片也都是通過這個原理實現的。簡單有效,唯一的缺憾就是一旦需要大量的素材或者序列圖來支撐。才能出來一個生動完整的動畫。(鼠標移到人物上播放動畫)
關鍵幀動畫,有優勢也有劣勢。
優勢:計算量小,只要序列圖的每幀銜接的好,動畫播放流暢自然。
劣勢:對於復雜的動畫,需要大量的序列圖做支撐。資源量太大對於web來說是一個不小的負擔,另外,就是對於這種基於序列圖播放的關鍵幀動畫,我們的可控度不太高,頂多能在一些特定的幀之間拋出一些事件做額外的處理,但是動畫本身的變化都是“固定”好的。
【骨骼動畫】
骨骼動畫的實現思路是從人體或動物的身體的運動方式而來的。動畫人物的身體(肉、皮膚)是一個網格(Mesh)模型,網格的內部是一個骨架結構。當人物的骨架運動時,身體就會跟着骨架一起運動。骨架是由一定數目的骨骼組成的層次結構,每一個骨骼的排列和連接關系對整個骨架的運動有很重要的影響。每一個骨骼數據都包含其自身的動畫數據。和每個骨架相關聯的是一個“蒙皮”(Skin)模型,它提供動畫繪制所需要的幾何模型(Vertex,Normal,etc)和紋理材質信息。每個頂點都有相應的權值(Weight),這些權值定義了骨骼的運動對有關頂點的影響因子。當把動畫人物的姿勢和全局運動信息作用到骨架上時,這個“蒙皮”模型就會跟隨骨架一起運動。
當前客戶端的大部分3D游戲或者2.5D的游戲,為了讓人物動作和動畫更加活潑,可控,可擴展,大多采用的都是這種骨骼動畫來實現的。
總體來說,這種動畫的實現復雜度也會是較高的。下面是幾個簡單的過程演示。
要做好骨骼動畫,一個是要了解其實現的原理,再深入一些可能還需要對前向動力學(FK)和逆向動力學(IK)做一些了解。
在我看來,骨骼動畫只要有一套數據和texture,按照一定的規則規范讀數據播放,其實並不是重點和難點,重點和難點是需要有一個方便易用的骨骼動畫的編輯器。可以做到以下幾點:
- 能對素材進行可視的切分編輯,把每一塊骨骼需要用的素材部分切分出來使用
- 能方便的對每一塊骨骼進行關節的添加,刪除,編輯。同時,在進行骨骼組裝的時候,關節能有鎖定的功能,方便后續的可視化動作編輯。
- 能方便的對骨骼進行一些拖拽,旋轉的可視化編輯操作。而且不能脫離關節,對已經綁定好關節的骨骼能做到前向或者逆向的聯動。
- 最后,有些有規律的動作其實不用自己一幀一幀的去擺,去添加,而是可以設置一個起始動作和結束動作,中間的補幀可以自動動態的插入。
這也是我正在嘗試實現的一個簡單的骨骼動畫編輯器所應該具備的一些功能。我會朝着這個方向去嘗試實現一個web的版本。
【結語】
本文只是對於canvas中實現各種動畫做了一個大致框架性的介紹和一些demo演示。后續如果有需要可以針對每一種動畫在實現的一些細節上進行更深入的講解。