iOS動(dòng)畫實(shí)戰(zhàn)之Lottie動(dòng)畫

介紹

如果你還不知道Lottie是什么, 那你真的out了.

如果把iOS動(dòng)畫分為兩類: 交互式動(dòng)畫, 播放式動(dòng)畫, 那么其中的播放動(dòng)畫完全可以使用Lottie來完成, 例如:

作為收藏按鈕, 是不是很活潑?

返回與菜單之間的切換, 生動(dòng)有趣!

還有各種形變動(dòng)畫.

這里先放上Lottie的地址: https://github.com/airbnb/lottie-ios

更棒的是, Lottie有各種不同的版本, 安卓, iOS, 前端都可以使用, 理論上動(dòng)畫做一套就可以共用, 大大的減少了工作量.

使用方法

  1. 集成環(huán)境: 移動(dòng)端同學(xué)集成Lottie框架, UI/UE同學(xué)集成AE的bodymovin插件
  2. 制作動(dòng)畫, 導(dǎo)出文件, 拖進(jìn)工程
  3. 創(chuàng)建LOTAnimationView, 并播放

非常簡(jiǎn)單, 下面看兩個(gè)實(shí)際例子

實(shí)戰(zhàn)

先看第一個(gè)例子:

典型的形變動(dòng)畫加上幾個(gè)普通動(dòng)畫融合在一起, 如果由程序員來寫, 確實(shí)還要花一番心思, 使用Lottie就非常容易了.

viewDidLoad時(shí)加載動(dòng)畫, 在視圖顯示出來時(shí)播放, 播放完了移除. 就是這么簡(jiǎn)單.

- (void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];
    
    if (_launchMask && _launchAnimation) {
        WeakObj(self);
        [_launchAnimation playWithCompletion:^(BOOL animationFinished) {
            
            [UIView animateWithDuration:0.3 animations:^{
                selfWeak.launchMask.alpha = 0;
            } completion:^(BOOL finished) {
                [selfWeak.launchAnimation removeFromSuperview];
                selfWeak.launchAnimation = nil;
                [selfWeak.launchMask removeFromSuperview];
                selfWeak.launchMask = nil;
            }];
        }];
    }
}


- (void)setupLaunchMask{
    _launchMask = [[UIView alloc] initWithFrame:self.view.bounds];
    
    [JRKeyWindow addSubview:_launchMask];
    
    _launchAnimation = [LOTAnimationView animationNamed:@"data"];
    _launchAnimation.cacheEnable = NO;
    _launchAnimation.frame = self.view.bounds;
    _launchAnimation.contentMode = UIViewContentModeScaleToFill;
    _launchAnimation.animationSpeed = 1.2;
    
    [_launchMask addSubview:_launchAnimation];
}

甚至可以用在引導(dǎo)頁中, 代碼都很簡(jiǎn)單, 就不重復(fù)貼了. 值得注意的是, 像這樣多次使用到Lottie時(shí)一定要注意素材的名字不能一樣, 否則動(dòng)畫就是錯(cuò)亂的, 簡(jiǎn)單講一講怎么改.

這是一個(gè)動(dòng)畫資源的文件結(jié)構(gòu), 如果修改了img_0.png及其文件夾, 則需要在Json文件中修改對(duì)應(yīng)的內(nèi)容

這就是Json文件中的內(nèi)容, 最上面一部分包含了素材路徑, 素材名稱, 注意修改好就ok.

第二個(gè)例子:

動(dòng)畫有小魚的尾巴搖動(dòng), 眼睛眨, 魚鰭煽動(dòng), 背后的小泡泡時(shí)隱時(shí)現(xiàn), 隨機(jī)運(yùn)動(dòng), 這讓程序員來一個(gè)個(gè)寫, 效率必然很低. 使用Lottie則簡(jiǎn)單很多, 我們公司的高級(jí)UI寫完這個(gè)簡(jiǎn)直不要太輕松.

讓UI同學(xué)導(dǎo)出動(dòng)畫時(shí)將第一幀截取出來作為啟動(dòng)頁靜態(tài)圖, 在第一個(gè)視圖加載的地方設(shè)置動(dòng)態(tài)動(dòng)畫.

- (void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];
    
    if (_launchMask && _launchAnimation) {
        WeakObj(self);
        [_launchAnimation playWithCompletion:^(BOOL animationFinished) {
            
            [UIView animateWithDuration:0.3 animations:^{
                selfWeak.launchMask.alpha = 0;
            } completion:^(BOOL finished) {
                [selfWeak.launchAnimation removeFromSuperview];
                selfWeak.launchAnimation = nil;
                [selfWeak.launchMask removeFromSuperview];
                selfWeak.launchMask = nil;
            }];
        }];
    }
}


- (void)setupLaunchMask{
    _launchMask = [UIImageView imageViewWithFrame:self.view.bounds image:[UIImage imageNamed:@"launchAnimationBg"]];
    
    [self.view addSubview:_launchMask];
    
    _launchAnimation = [LOTAnimationView animationNamed:@"launchAnimation"];
    _launchAnimation.cacheEnable = NO;
    _launchAnimation.frame = self.view.bounds;
    _launchAnimation.contentMode = UIViewContentModeScaleToFill;
    _launchAnimation.animationSpeed = 1.2;
    
    [_launchMask addSubview:_launchAnimation];
}

幾點(diǎn)值得注意的是:

  1. 我這創(chuàng)建一個(gè)UIImageView作為背景, 是拆分了動(dòng)畫, 將不動(dòng)的部分作為背景, 避免內(nèi)存中加載的圖片過多, 后面會(huì)細(xì)說這個(gè)問題.

  2. LOTAnimationView這個(gè)類就是動(dòng)畫本身了, 也可以設(shè)置contentMode, 所以為了適配, 這個(gè)屬性應(yīng)該與啟動(dòng)頁圖片一致(建議啟動(dòng)頁用Storyboard + UIImageView).

  3. 在視圖加載完成之后調(diào)用_launchAnimation的play方法, 完成之后漸變色隱藏并置空.

很容易的, 一個(gè)精美的啟動(dòng)動(dòng)畫就完成了.

總結(jié)

看完了本篇文章, 你會(huì)發(fā)現(xiàn)動(dòng)畫竟然如此簡(jiǎn)單, 那我們以后動(dòng)畫全用Lottie來實(shí)現(xiàn)? 其實(shí)Lottie也有一定的限制

Lottie是基于CALayer的動(dòng)畫, 所有的路徑預(yù)先在AE中計(jì)算好, 轉(zhuǎn)換為Json文件, 然后自動(dòng)轉(zhuǎn)換為L(zhǎng)ayer的動(dòng)畫, 所以性能理論上是非常不錯(cuò)的, 在實(shí)際使用中, 確實(shí)很不錯(cuò), 但是有幾點(diǎn)需要注意的:

  • 如果使用了素材, 那么素材圖片的每個(gè)像素都會(huì)直接加載進(jìn)內(nèi)存, 并且是不能釋放掉的(實(shí)測(cè), 在框架中有個(gè)管理cache的類, 并沒有啟動(dòng)到作用, 若大家找到方法請(qǐng)告訴我), 所以, 如果是一些小圖片, 加載進(jìn)去也還好, 但是如果是整頁的啟動(dòng)動(dòng)畫, 如上面的啟動(dòng)頁動(dòng)畫, 不拆分一下素材, 可能一個(gè)啟動(dòng)頁所需要的內(nèi)存就是50MB以上. 如果不使用素材, 而是在AE中直接繪制則沒有這個(gè)問題.

  • 如果使用的PS中繪制的素材, 在AE中做動(dòng)畫, 可能在動(dòng)畫導(dǎo)出的素材中出現(xiàn)黑邊, 我的解決辦法是將素材拖入PS去掉黑邊, 同名替換.

  • 拆分素材的辦法是將一個(gè)動(dòng)畫中靜態(tài)的部分直接切出來加載, 動(dòng)的部分單獨(dú)做動(dòng)畫

  • 如果一個(gè)項(xiàng)目中使用了多個(gè)Lottie的動(dòng)畫, 需要注意Json文件中的路徑及素材名稱不能重復(fù), 否則會(huì)錯(cuò)亂

  • 不支持漸變色

  • 不支持AE中的mask屬性

  • Lottie先天就支持播放式動(dòng)畫, 對(duì)于交互式動(dòng)畫有個(gè)animationProgress的屬性(待核實(shí))

基于以上的問題, 建議使用Lottie的場(chǎng)合為復(fù)雜的播放式形變動(dòng)畫, 因?yàn)樾巫儎?dòng)畫由程序員一點(diǎn)點(diǎn)的寫路徑確實(shí)不直觀且效率低. 但即便如此, Lottie也是我們?cè)贑oreAnimation之后一個(gè)很好的補(bǔ)充.

以上健唄的Demo地址: https://github.com/syik/JR

直播伴侶地址: https://github.com/syik/BulletAnalyzer

這是一個(gè)已經(jīng)上架的App, 大家可以直接在App Store中找到使用. 上一篇文章為此App中CoreAnimation與CoreGraphics可交互式圖表實(shí)戰(zhàn).
若大家覺得寫得有用, 不吝嗇打賞一個(gè)Star~, 謝謝~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市府树,隨后出現(xiàn)的幾起案子埠褪,更是在濱河造成了極大的恐慌脏款,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,682評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件窟勃,死亡現(xiàn)場(chǎng)離奇詭異闽烙,居然都是意外死亡日缨,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門家卖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來眨层,“玉大人,你說我怎么就攤上這事上荡∨坑#” “怎么了?”我有些...
    開封第一講書人閱讀 165,083評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵酪捡,是天一觀的道長(zhǎng)叁征。 經(jīng)常有香客問我,道長(zhǎng)逛薇,這世上最難降的妖魔是什么捺疼? 我笑而不...
    開封第一講書人閱讀 58,763評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮永罚,結(jié)果婚禮上啤呼,老公的妹妹穿的比我還像新娘。我一直安慰自己呢袱,他們只是感情好官扣,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著产捞,像睡著了一般醇锚。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,624評(píng)論 1 305
  • 那天焊唬,我揣著相機(jī)與錄音恋昼,去河邊找鬼。 笑死赶促,一個(gè)胖子當(dāng)著我的面吹牛液肌,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播鸥滨,決...
    沈念sama閱讀 40,358評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼嗦哆,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了婿滓?” 一聲冷哼從身側(cè)響起老速,我...
    開封第一講書人閱讀 39,261評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎凸主,沒想到半個(gè)月后橘券,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,722評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡卿吐,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年旁舰,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嗡官。...
    茶點(diǎn)故事閱讀 40,030評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡箭窜,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出衍腥,到底是詐尸還是另有隱情磺樱,我是刑警寧澤,帶...
    沈念sama閱讀 35,737評(píng)論 5 346
  • 正文 年R本政府宣布婆咸,位于F島的核電站坊罢,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏擅耽。R本人自食惡果不足惜活孩,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望乖仇。 院中可真熱鬧憾儒,春花似錦、人聲如沸乃沙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽警儒。三九已至训裆,卻和暖如春眶根,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背边琉。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工属百, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人变姨。 一個(gè)月前我還...
    沈念sama閱讀 48,237評(píng)論 3 371
  • 正文 我出身青樓族扰,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親定欧。 傳聞我的和親對(duì)象是個(gè)殘疾皇子渔呵,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容