Lottie運行流程分析

1. Lottie是什么?

Airbnb 開源的跨平臺動畫庫,適用于 iOS、Android、React Native 和 Web 等平臺,它可以解析使用 Bodymovin 導(dǎo)出為 json 的 Adobe After Effects 動畫,允許應(yīng)用程序像使用靜態(tài)圖像一樣輕松使用動畫

2. 如何使用?

2.1 基本用法

lottie-android 有兩種引入方式:

1. xml方式

<com.airbnb.lottie.LottieAnimationView
        android:id="@+id/animation_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"

        app:lottie_rawRes="@raw/hello_world"
        // or
        app:lottie_fileName="hello_world.json"

        // Loop indefinitely
        app:lottie_loop="true"
        // Start playing as soon as the animation is loaded
        app:lottie_autoPlay="true" />

2. 編程方式

LottieAnimationView animationView = ...

animationView.setAnimation(R.raw.hello_world);
// or
animationView.setAnimation(R.raw.hello_world.json);

animationView.playAnimation();

2.2 更多API

lottie 提供了多種對動畫的操作:

playAnimation() //播放動畫
pauseAnimation()    //暫停動畫
setMinFrame()   //設(shè)置起始幀
setMaxFrame()   //設(shè)置結(jié)束幀
setRepeatCount()    //設(shè)置重復(fù)次數(shù)
setSpeed()  //設(shè)置播放速度

此外,lottie 也提供一系列監(jiān)聽:

addAnimatorListener()   //start、end、cancel、repeat回調(diào)
addAnimatorUpdateListener() //update回調(diào)

其他平臺及用法參考官方文檔

3. Lottie實現(xiàn)原理?

3.1 整體關(guān)系圖

從上面不難看出,主要有 3 個橋梁對象

  • LottieAnimationView:門面對象,對外暴露統(tǒng)一的調(diào)用接口,我們通過它輕松實現(xiàn)各種動畫效果
  • LottieComposition:負(fù)責(zé)解析 json 描述文件,把 json 內(nèi)容轉(zhuǎn)成 Java 數(shù)據(jù)對象
  • LottieDrawable:負(fù)責(zé)繪制,把 LottieComposition 轉(zhuǎn)成的數(shù)據(jù)對象繪制成 Drawable 并顯示到 View 上

LottieComposition 及其往左是數(shù)據(jù)側(cè)。AE 動畫的組成和 PS 很相似,整個動畫用一個 LottieComposition 對象來承裝,一個動畫又包含了若干個圖層 Layer,在圖層上我們可以進(jìn)行一些操作 AnimatableTransform,圖上的 o r p a s 分別表示 5 種變換 opacity、rotate、position、anchor、scale

這里還有一個概念叫關(guān)鍵幀,我們都知道動畫的單位是幀,動畫運行的本質(zhì)就是微分,即預(yù)先設(shè)定初始值和目標(biāo)值,在一段時間內(nèi)不斷改變這個值向目標(biāo)靠近,這個初始值和目標(biāo)值就可以認(rèn)為是關(guān)鍵幀,當(dāng)然在這之間也是能夠插入多個關(guān)鍵值的,這樣就會有多個關(guān)鍵幀了

LottieDrawable 及其往右是渲染側(cè)。數(shù)據(jù)側(cè)的對象只是存儲了數(shù)據(jù),Lottie 會將這些數(shù)據(jù)轉(zhuǎn)換成具備渲染能力的對象,這里他們是有對應(yīng)關(guān)系的,如:CompositionLayer 和 LottieComposition,BaseLayer 和 Layer,TransformKeyframeAnimation 和 AnimatableTransform,KeyframeAnimation 和 Keyframe,而 LottieDrawle 就是一張畫布,它擁有一個 Canvas,當(dāng)我們開始播放動畫,這些圖層便一層一層的在 Canvas 上進(jìn)行繪制,隨著時間(progress)的推進(jìn),各圖層不斷根據(jù)當(dāng)前進(jìn)度計算新的狀態(tài)值,并重復(fù)繪制過程,圖像便動了起來

3.2 主線運行流程

1. json文件內(nèi)容
動畫的數(shù)據(jù)模型從 AE 到我們代碼中會經(jīng)歷如下幾個變化:




從上面可以看出,動畫的數(shù)據(jù)模型中總有下面的包含關(guān)系:


這里再借用一張圖,看看 json 文件中都描述了些什么內(nèi)容:

上圖一些關(guān)鍵項后面都帶了解釋。這里第一部分是 json 文件的外層結(jié)構(gòu),主要是 layers 這個數(shù)組包含了所有的圖層信息,layers 中的 ks 中包含了所有的變換信息,也就是上面一直提到的 o r p a s 變換

2. 動畫運行流程
知道了 json 內(nèi)容的含義,接下來再來看看動畫是怎么運行的,下面是 Lottie 的運行流程圖:

整個的執(zhí)行邏輯大致是這樣的:

  1. 通過 Factory.fromJsonSync 將 json 文件解析成為 LottieComposition
  2. 根據(jù) LottieComposition 中的數(shù)據(jù)來構(gòu)造具備渲染能力的 CompositionLayer
  3. 啟動 ValueAnimator 去不斷監(jiān)聽動畫進(jìn)度,一旦進(jìn)度改變就回調(diào)更新函數(shù)
  4. 各個圖層根據(jù)當(dāng)前進(jìn)度(progress)計算自身新的狀態(tài)
  5. LottieDrawable 將它持有的 Canvas 傳給各圖層進(jìn)行繪制,最終顯示到 View 上

4. Lottie Q&A?

4.1 與其他加載方式的比較

  • 視圖動畫。 無法真正改變 view 的屬性,只有視覺上的效果
  • 屬性動畫。 難以完成設(shè)計師給出的一些精美復(fù)雜的動畫效果
  • gif 視頻。 體積是 json 的兩倍以上,存在交互障礙,并且以固定大小渲染,無法按比例放大以匹配大型和高密度屏幕
  • png 序列。 需要大量的圖片素材,文件大小通常是 json 大小的 30-50 倍,動畫播放時會占用很多內(nèi)存,也無法按比例放大
  1. Lottie優(yōu)點如下:
  • 100% 還原設(shè)計師給出的各種復(fù)雜動畫效果
  • 簡單的實現(xiàn)、控制動畫的播放,開發(fā)效率大大提高
  • 可動態(tài)配置下發(fā),實時替換動畫效果
  1. Lottie性能問題:
  • Mask 和 mattes(蒙板和遮罩)對動畫性能會有較大影響,不宜在列表中使用包含 mask 或 mattes 的動畫
  • 列表中使用動畫,要使用緩存 LottieAnimationView.setAnimation(String, CacheStrategy),避免內(nèi)存抖動
  • Lottie 中 ImageLayer 對圖片的解碼是在主線程的,并且沒有對 Bitmap 重用,可以自己將圖片解碼的邏輯遷移到子線程,并增加對 Bitmap 的緩存來提高性能

4.2 Lottie的使用場景

  1. Lottie 不適用的兩種場景:
  • 給 View 本身添加動畫(如:從右下角到移動到頁面中,并逐漸放大的過渡效果)
  • 動畫中有動態(tài)內(nèi)容(如:需要顯示一個數(shù)量,多少來自數(shù)據(jù)庫/網(wǎng)絡(luò))
  1. Lottie 非常適合像一段動畫的播放這樣的場景使用
  • json 文件的大小比 gif 文件小很多
  • 能夠非常方便的控制動畫播放,如:速率、范圍
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1、通過CocoaPods安裝項目名稱項目信息 AFNetworking網(wǎng)絡(luò)請求組件 FMDB本地數(shù)據(jù)庫組件 SD...
    陽明AI閱讀 16,192評論 3 119
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對...
    cosWriter閱讀 11,631評論 1 32
  • 虛擬的世界不可怕,可怕的是人格虛擬。一個虛擬的畫面,可以讓人聯(lián)想到美的畫面,也可以讓人聯(lián)想到丑陋的景象,這是需要...
    秋日雛菊閱讀 601評論 0 1
  • 周日下午天氣陽光明媚,早上在公園玩了一上午的加加在車?yán)锼藗€午覺。想著條件俱全,讓她去找外公爬山,我心想這樣可陪陪...
    roserao閱讀 200評論 0 0
  • 一一你相信頓悟這一說法嗎?一一我相信。雖然我不確定我是不是頓悟了,但我知道在那一刻我的大腦突然出現(xiàn)三個紙:人如紙。...
    帥鍋子閱讀 430評論 0 1

友情鏈接更多精彩內(nèi)容