lottie是一個跨平台的動畫庫,通過AE(After Effects)制作動畫,再通過AE插件Bodymovin導出Json文件,最終各個終端解析這個Json文件,還原動畫。本文中我只介紹前端用到的庫lottie-web。
對比三種常規的制作動畫方式
- Png序列幀
- 2.Gif圖
- 前端Svg API
先對位圖與矢量圖有一個基本的概念。
矢量圖就是使用直線和曲線來描述的圖形,構成這些圖形的元素是一些點、線、矩形、多邊形、圓和弧線等,它們都是通過數學公式計算獲得的,具有編輯后不失真的特點。
位圖是由稱作像素(圖片元素)的單個點組成的,放大會失真。
Png序列幀
用Png序列幀是也容易理解,用css keyframes操作每一幀需要展示的圖片,缺點也很明顯,每一幀都是一張圖片,占比較大的體積。當然也可以將圖片合並成精靈圖(Sprites Map),可參考這個方案,使用 gka 一鍵生成幀動畫。Png也是位圖,放大會失真,不過可以通過增大圖片尺寸,避免模糊。
Gif圖
如果之前沒有用過動畫,用Gif圖是最簡單的,只需要引入一張圖。但是Gif圖是位圖,不是矢量圖,放大會虛。
前端Svg API
Svg API對於動畫初學者不太友好,你要實現一個自定義的動畫,需要了解Svg的所有的API,雖然它的屬性與css的動畫有一些相似。它是矢量圖,不失真。
lottie
而lottie是一個不太占體積,還原度高,對於初學者友好的庫。設計師制作好動畫,並且利用Bodymovin插件導出Json文件。而前端直接引用lottie-web庫即可,它默認的渲染方式是svg,原理就是用JS操作Svg API。但是前端完全不需要關心動畫的過程,Json文件里有每一幀動畫的信息,而庫會幫我們執行每一幀。
前端安裝lottie-web插件
npm install lottie-web
代碼調用
import lottie from 'lottie-web'; this.animation = lottie.loadAnimation({ container: this.animationRef.current, renderer: 'svg', loop: false, autoplay: false, animationData: dataJson, assetsPath: CDN_URL, });
介紹一個每個屬性的意思。
- container 當前需要渲染的DOM
- renderer,渲染方式,默認是Svg,還有Html和Canvas方案。
- loop 是否循環播放
- autoplay 是否自動播放
- animationData AE導出的Json,注意,這里不是路徑
- assetsPath Json文件里資源的絕對路徑,webpack項目需要配合這個參數。
動畫的播放與暫停,如果動畫需要用戶觸發與暫停,需要有一個切換操作(toggle)
this.animation.play(); this.animation.pause();
動畫執行過程中的鈎子,可以對動畫有一定的控制權
- complete
- loopComplete
- enterFrame
- segmentStart
- config_ready(初始配置完成)
- data_ready(所有動畫數據加載完成)
- DOMLoaded(元素已添加到DOM節點)
- destroy
// 動畫播放完成觸發 anm.addEventListener('complete', anmLoaded); // 當前循環播放完成觸發 anm.addEventListener('loopComplete', anmComplete); // 播放一幀動畫的時候觸發 anm.addEventListener('enterFrame', enterFrame);
打包時圖片資源路徑
webpack工程需要注意Json文件如果有圖片資源(Png或者Svg),需要將文件放在項目的根目錄的static下。這樣打包的時候,圖片會被打包,並且后綴名不會被改變,當然需要配合assetsPath這個參數,設置圖片的絕對路徑。而CDN的路徑可以通過process.env.CDN_URL
從webpack傳到前端代碼中。
關於源碼
關於lottie源碼解析,這位老哥已經分析的挺到位了,Lottie原理與源碼解析。盡管lottie也一直在迭代,但是順着這篇解析應該也能理清源碼。以及Svg動畫的介紹,SVG 動畫精髓