iOS 的動(dòng)畫實(shí)現(xiàn)早已不是什么新鮮話題鉴腻。
相信很多 iOS 開發(fā)不但熟練掌握了動(dòng)畫的使用方法司致,很多甚至深入到底層實(shí)現(xiàn)辙售。
當(dāng)然,本文的重點(diǎn)并不是介紹 iOS 的動(dòng)畫 API 如何使用骗村,而是想簡(jiǎn)單聊一下對(duì)于復(fù)雜動(dòng)畫框架的選擇側(cè)重嫌褪。
動(dòng)畫的分類
這里我將 iOS 中動(dòng)畫的種類以 API
調(diào)用的方式分為四類, 對(duì) iOS 底層動(dòng)畫實(shí)現(xiàn)的機(jī)制講解并不是本文的重點(diǎn),如果有同學(xué)對(duì)這塊感興趣胚股,網(wǎng)上都很多資料可供參考笼痛。例如這一篇就講的不錯(cuò).
關(guān)于iOS動(dòng)畫底層的實(shí)現(xiàn):https://lision.me/ios-rendering-process/
-
基于 UIView 的動(dòng)畫:即主要以修改 UIView 屬性來實(shí)現(xiàn)的的一些動(dòng)畫, 例如
UIView.animation
相關(guān)的一系列 API。主要實(shí)現(xiàn)的動(dòng)畫效果常見的有 位移
大小
transform
顏色變換
Layer 層的動(dòng)畫:以官方的
CABasicAnimation
和 facebook 的pop
為主缨伊。Layer 層的動(dòng)畫的表現(xiàn)力強(qiáng)于 UIView 動(dòng)畫
能夠?qū)崿F(xiàn)復(fù)雜的 keyframe animation
有 CALayer 有 3DTransformation摘刑,所以可以用 layer 層動(dòng)畫做 3D 動(dòng)畫。
-
特別是 pop刻坊,他在 SpringAnimation 中提供了
dynamicsTension
和dynamicsMass
兩個(gè)屬性枷恕,所以可以和很多工具無縫銜接,例如Principle
-
可交互動(dòng)畫類型:UIViewPropertyAnimator
這類動(dòng)畫天然支持和手勢(shì)的交互谭胚,例如
continueAnimation
等方法徐块, 當(dāng)然,除了UIView.animation
完全不支持交互式動(dòng)畫以外灾而,其實(shí) CABasicAnimation 也可以利用layerSpeed
和timeOffset
等方法組合起來配合手勢(shì)實(shí)現(xiàn)交互式動(dòng)畫胡控,不過難度和繁瑣程度有嘗試過的開發(fā)應(yīng)該能感受到。PropertyAnimator 可以視為 UIView.animation 的 API 優(yōu)化版和功能增強(qiáng)版绰疤,對(duì)于組合動(dòng)畫铜犬,交互式動(dòng)畫等,在設(shè)計(jì)上的方便程度和易用程度的提升是革命性的轻庆。
Gif 類動(dòng)畫
此類動(dòng)畫本質(zhì)是播放序列幀。
很多第三方庫可以支持敛劝,例如 YYImage 和 FLAnimateImage
gif 動(dòng)畫最大的問題是大小和質(zhì)量余爆,因?yàn)?gif 本質(zhì)是多張圖片的組合播放,所以一旦動(dòng)畫時(shí)長(zhǎng)超過 10s夸盟, 分辨率較高蛾方,gif 的大小就直奔 5mb 以上去了。
gif 動(dòng)畫的性能也是比較大的問題上陕,有興趣的同學(xué)可以測(cè)試一下同屏多個(gè) gif 渲染桩砰,手機(jī)幀率會(huì)下降到什么程度
所以除了在表情包市場(chǎng)的少量領(lǐng)域,幾乎沒有人用 gif 來實(shí)現(xiàn) app 里的動(dòng)畫释簿。
即便是表情包市場(chǎng)亚隅,也普遍以 SVG 或者 mp4 格式代替了。
非人力可為的復(fù)雜動(dòng)畫
當(dāng)然庶溶,上述的三種動(dòng)畫尚能稱之為人力可為煮纵。什么意思呢?
指的是偏螺,程序員對(duì)于上述動(dòng)畫依舊能夠利用足夠的耐心和反復(fù)的嘗試來拆解和實(shí)現(xiàn)行疏。但是,下面我要說的這類動(dòng)畫套像,不依靠設(shè)計(jì)工具純靠編程是幾乎無法實(shí)現(xiàn)的酿联。比如下面這個(gè)
即便拋去復(fù)雜動(dòng)畫難以通過手?jǐn)]代碼來實(shí)現(xiàn)這一現(xiàn)實(shí)問題。還有一點(diǎn)不可忽視的原因是,原生代碼實(shí)現(xiàn)動(dòng)畫的成本之高也到了難以忍受的程度了贞让。
從設(shè)計(jì)動(dòng)畫到多端實(shí)現(xiàn)周崭,從 iOS 到 Android 到 RN 甚至 flutter,一套動(dòng)畫如果采取原生實(shí)現(xiàn)的話震桶,需要寫 4 套代碼休傍。這成本是絕對(duì)不可接受的。因此蹲姐,lottie 和 pag 也應(yīng)運(yùn)而生了磨取。
Lottie VS PAG
lottie 相信大家并不模式,是 airbnb 針對(duì)復(fù)雜動(dòng)畫場(chǎng)景研發(fā)的框架柴墩,包含多個(gè)端和一個(gè) ae 插件 bodymovin 來導(dǎo)出動(dòng)畫忙厌。
pag 相對(duì)而言可能陌生一點(diǎn),pag 是騰訊新推出的一款完整的動(dòng)畫工作流江咳。提供從AE(Adobe After Effects)導(dǎo)出插件逢净,到桌面預(yù)覽工具,再到各端的跨平臺(tái)渲染 SDK歼指。
至于為什么會(huì)調(diào)研兩個(gè)框架爹土,則是由于我最近要開發(fā)一款表情和禮物特效的 UI 框架,所以需要調(diào)研市面上能夠?qū)崿F(xiàn)復(fù)雜動(dòng)效的框架踩身,所以我針對(duì)這兩個(gè) SDK 做了一些研究和比較胀茵。
在對(duì)比兩個(gè)框架之前,我們需要先介紹一下挟阻,lottie 和 pag 的工作原理到底是什么琼娘,他們又是怎么在端上實(shí)現(xiàn)復(fù)雜動(dòng)畫的。
我們先來看一下使用 lottie 的簡(jiǎn)單流程附鸽。
pag 的流程脱拼。
從兩個(gè)框架的流程圖可以看出,工作流大體相似坷备,如
由 AE 生成動(dòng)畫
附帶 AE 插件熄浓,可以通過插件導(dǎo)出動(dòng)畫
lottie 的 bodymovin
PAG 的 PAGViewer
預(yù)覽
導(dǎo)出文件
端上的渲染 SDK
框架的比較
對(duì)于一個(gè)成熟項(xiàng)目而言懈糯,選擇一個(gè)框架是需要非常謹(jǐn)慎的堕花。
考慮到接入到項(xiàng)目之后返弹,框架會(huì)伴隨著項(xiàng)目的發(fā)展和演進(jìn)旺订,所以我們需要從多個(gè)維度來看盖腕,到底哪個(gè)適合徐绑,或者說哪個(gè)更好队橙。
我主要從下列幾個(gè)維度進(jìn)行了比較妥箕。
AE 插件能力
插件能力代表了這兩個(gè)框架能夠使用多少 AE 的功能鸿摇,也即意味著功能的多寡石景。
我根據(jù)兩個(gè)框架公開的信息對(duì)比了一下。
- PAG 插件能力列表: https://pag.io/docs/ae-support.html
- lottie 插件能力列表: https://aescripts.com/bodymovin/
結(jié)論大概如下:Lottie和SVGA都使用AE Script SDK來導(dǎo)出AE工程,但是AE Script SDK本身存在一定限制潮孽,不能訪問AE文件中的所有屬性揪荣,PAG則使用AE C++ SDK,能訪問AE文件中所有屬性和一些高級(jí)API往史,能夠?qū)崿F(xiàn)對(duì)AE文件的完整導(dǎo)出仗颈。
導(dǎo)出文件
導(dǎo)出文件的選擇上,lottie 選擇了 JSON椎例, PAG 采用了類似于 protocolbuffer 的二進(jìn)制文件來實(shí)現(xiàn)挨决。
二者比較我覺的能力上各有優(yōu)劣。
lottie 采用 JSON 可讀性強(qiáng)订歪,但是承載AE特性能力差脖祈,文件體積大,解碼速度慢刷晋。
PAG采用二進(jìn)制的編碼方法盖高,優(yōu)勢(shì)大概有:
- 自研編解碼器
- 動(dòng)態(tài)比特位壓縮,冗余信息極少眼虱,文件體積小喻奥,解碼速度快
- 支持圖片和音頻信息編碼。
不過基于插件導(dǎo)出文件而言捏悬,我不認(rèn)為會(huì)有人去人肉讀取 bodymovin 導(dǎo)出的 JSON 文件去修改映凳。
所以這一點(diǎn)上我認(rèn)為 PAG 的做法更有優(yōu)勢(shì)。
SDK 的實(shí)現(xiàn)
- lottie 基于各端的 native 來實(shí)現(xiàn)
- PAG 基于 C++ 邮破,在端上進(jìn)行了抹平。
基于各端的 native 的渲染其實(shí)渲染一致性上會(huì)是一個(gè)問題仆救,比如 RN 相對(duì)于 Flutter是一個(gè)很好地對(duì)照例子抒和。一個(gè)是代碼轉(zhuǎn)譯,一個(gè)是自研渲染引擎 skia, 所以 Flutter 的表現(xiàn)力上要比 RN 這種依賴端上的框架強(qiáng)很多彤蔽。所以我認(rèn)為 C++ 作為不同端的統(tǒng)一渲染是一種更好的方法摧莽。
跨平臺(tái)的支持
平臺(tái)支持 | lottie | PAG |
---|---|---|
Android | ? | ? |
iOS | ? | ? |
Web | ? | ? |
mac OS | ? | ? |
Linux | ? | ? |
Windows | ? | ? |
端上的支持 PAG 更豐富一些,也是依托于底層采用 C++的實(shí)現(xiàn)顿痪,抹平了端上的差異镊辕,所以支持的平臺(tái)更多。
性能
性能我認(rèn)為是復(fù)雜動(dòng)畫框架最重要的一環(huán)蚁袭,特別是移動(dòng)端上同屏多動(dòng)畫渲染的性能征懈,其實(shí)直接決定了 SDK 的使用與否。我認(rèn)為在性能的比對(duì)上揩悄,其實(shí)存在一票否決的能力卖哎。
根據(jù)我能搜到的信息,我把兩個(gè)框架的性能 PK 相關(guān)信息摘錄了一下。
矢量動(dòng)畫文件對(duì)比
矢量動(dòng)畫渲染性能
結(jié)論
經(jīng)過一些調(diào)研亏娜,和我實(shí)際下載體驗(yàn)了兩個(gè)框架焕窝,我覺得在工具,插件维贺,底層實(shí)現(xiàn)和渲染它掂, PAG 對(duì)我而言是更好的一個(gè)動(dòng)畫框架。
當(dāng)然溯泣,每個(gè)人面對(duì)的項(xiàng)目和情況不同虐秋,本文僅做參考。也希望有人能夠在更多層面進(jìn)行比對(duì)发乔,提出不同方向的反饋熟妓。
關(guān)于兩個(gè)框架更多實(shí)現(xiàn)的細(xì)節(jié),也可以參考我上面發(fā)的鏈接地址栏尚。