我們知道,做動畫有多種形式,可以用CSS的animation,也可以用Canvas,或者是用JS控制CSS的屬性形成動畫。我們經常使用CSS做一些比較簡單的動畫,像過度、加載的動畫,對於一些比較復雜的,要麽做成gif,要麽用Canvas,使用Canvas的控制粒度可以很細,同時工作量相對也比較大。做動畫還有其它的方式,那就是使用After Effect(AE)/flash/Premiere(Pr)/會聲會影等,這種可視化的制作方式相對於直接寫Canvas來說,會更容易簡單自然。做動畫本身應該使用工具進行制作,但是這種視頻軟件做出來的動畫最後都是生成視頻文件,並且通常體積還很大,沒有辦法移植到網頁上去。
然而好消息是,現在我們可以使用AE做動畫,然後使用bodymovin插件導出成html文件進行播放。AE是Adobe推出的一個很出名視頻後期處理軟件,有些電影就是用AE做的,如變形金剛,還有人把AE當成加強版PS使用。也就是說假如我們可以AE做出一些電影級別的效果,然後用html播放,那是一件多麽酷炫的事情。
1. 安裝bodymovin
bodymovin是一個AE的一個開源的第三方擴展, github地址 。上面可以 下載這個插件 。然後再安裝一個 ZXPInstaller 來安裝這個文件,然後重啟AE就可以了,當然前提是你要安裝一個AE,支持AE CC版本:
After Effects CC 2017, CC 2015.3, CC 2015, CC 2014安裝完之後,點擊AE的菜單Window -> Extensions -> Bodymovin就會彈出一個窗口:
2. 使用AE制作動畫
我相信很多人都沒有玩過AE,所以這裏我簡單地介紹一下。首先新建一個工程(project),然後新建一個合成(composition),選擇1080p/29fps,時長為10s,然後它就會創建一個10s的合成。如下時間軸面板的顯示:
這個時間軸將會是頻繁操作的地方。然後點擊文字工具,在上方的預覽窗口點擊創建文字,然後把它拖到窗口外面,因為我們準備做一個文字從外面進來的動畫,所以剛開始它是在外面的。把上圖右邊的藍色豎線表示的當前時間拖到0s的位置,然後在左邊的文字圖層的Position屬性打一個關鍵幀,如下圖所示:
然後把時間線挪到3s的位置,改變文字的Position,把它挪到窗口的中間,這個時間AE會自動在時間線的位置打一個關鍵幀,如下圖所示:
然後按一下空格鍵進行預覽,預覽窗口就會播放起了我們剛剛設定的動畫:
你會發現,這個過程不是和CSS的keyframe動畫一樣的麽?沒錯!動畫的原理都是一樣,通過設定關鍵幀制作動畫。現在來比較一下用AE和用CSS/Canvas做這個動畫的區別。
3. 關鍵幀動畫
現在用CSS做這個動畫,如下代碼所示:
.text{ animation: move 3s linear infinite; } @keyframes move{ from{ transform: translateX(-320px); } to{ transform: translateX(100px); } } <div class="container"> <p class="text">Hello, frontend</p> </div>
我們給animation添加一個動畫,這個動畫有兩個關鍵幀,分別在0%和100%的位置,需要變化的是transform的屬性。這段代碼在瀏覽器運行,就會有剛剛用AE做的動畫的效果了。如果用Canvas呢,應該怎麽實現呢?
如下代碼所示:
<canvas id="text-move" width="600" height="400"></canvas> <script> !function(){ window.requestAnimationFrame(draw); var canvas = document.querySelector("text-move"), ctx = canvas.getContext("2d"); function draw(){ //計算文字position var textPosition = getPosition(); drawText(); window.requestAnimationFrame(draw); } }();
這個是canvas動畫的基本框架,先註冊requestAnimationFrame的draw函數,使得瀏覽器在重新繪制屏幕時會先調一下這個函數,理想情況下1s會繪制60幅圖片,也就是說1s為60幀/60fps。
上面代碼最關鍵的地方是在於計算文字的位置position,同樣地,也是先設定初始位置和終點位置還有動畫時間,從而知道移動的速度v,即每1s多少距離,記錄一個動畫開始時間,然後在每次draw的時候用Date.now()獲取當前時間減掉開始時間,就得到時間t,然後用v * t就可以得到位移。這就是用Cavans做動畫的基本原理,我們看到,用Canvas需要自己實現一個關鍵幀系統。
從抽象級別來看的話,AE > CSS >> Canvas,使用AE我只需要拖一拖,然後打上幾個關鍵幀,而使用CSS,我需要把我的操作寫成代碼,而使用Canvas我需要從0開始一點一點去控制,當然你可以使用一些動畫和遊戲的引擎去控制。所以如果有一個可視化界面讓你去完成一些復雜的操作,和讓你一行一行去寫代碼的方式選擇的話,我想大部分人應該會選擇前者。當然這兩者的區別不僅僅是操作上的簡便性,使用AE借用插件還可以很快地制作出一些復雜的效果。
4. bodymovin小試牛刀
剛剛已經用AE做了一個最簡單的動畫,現在把它導出來。打開bodymovin,選中合層,和輸出路徑,如下圖所示:
然後點擊Render,完成它會導出一個json文件,打開這個導出的文件:
{“v”:”4.10.1″,”fr”:29.9700012207031,”ip”:0,”op”:95.0000038694293,”w”:1920,”h”:1080,”nm”:”Comp 1″,”ddd”:0,”assets”:[],”fonts”:{“list”:[{“origin”:0,”fPath”:””,”fClass”:””,”fFamily”:”Myriad Pro”,”fWeight”:””,”fStyle”:”Regular”,”fName”:”MyriadPro-Regular”,”ascent”:70.9991455078125}]},”layers”:[{“ddd”:0,”ind”:1,”ty”:5,”nm”:”hello, frontend”,”sr”:1,”ks”:{“o”:{“a”:0,”k”:100,”ix”:11},”r”:{“a”:0,”k”:0,”ix”:10},”p”:{“a”:1,”k”:[{“i”:{“x”:0.833,”y”:0.833},”o”:{“x”:0.167,”y”:0.167},”n”:”0p833_0p833_0p167_0p167″,”t”:0, “s”:[-1017,692,0],”e”:[458,692,0] ,”to”:[245.83332824707,0,0],”ti”:[-245.83332824707,0,0]},{“t”:90.0000036657751}],”ix”:2},”a”:{“a”:0,”k”:[0,0,0],”ix”:1},”s”:{“a”:0,”k”:[100,100,100],”ix”:6}},”ao”:0,”t”:{“d”:{“k”:[{“s”:{“s”:164,”f”:”MyriadPro-Regular”,”t”:”hello, frontend”,”j”:0,”tr”:0,”lh”:196.8,”ls”:0,”fc”:[0,0.64,1]},”t”:0}]},”p”:{},”m”:{“g”:1,”a”:{“a”:0,”k”:[0,0],”ix”:2}},”a”:[]},”ip”:0,”op”:300.00001221925,”st”:0,”bm”:0}]}
這個文件記錄了所有動畫的過程,如上加粗字體是我們剛剛打的兩個關鍵幀的位置。然後安裝一下bodymovin的引擎,可在github上面下載bodymovin.js或者是npm install一下:
npm install bodymovin
然後就可以使用bodymovin了,如下html:
<!DOCType html> <html> <head> <meta charset="utf-8"> </head> <body> <div id="animation-container" style="width:100%"></div> <script src=http://www.tuicool.com/articles/"node_modules/bodymovin/build/player/bodymovin.js">