Airbnb開源項目Lottie
過去在iOS, Android甚至React Native apps中製作一些複雜的動畫都需要花上一些時間並且有一定難度的。
我們不是放入一堆不同大小的圖檔就是寫出很長一串的Code,也因為這樣許多App都沒有在做動畫效果。
想到每一次設計師將動畫效果放出來以後,我們也只是用Code去呈現一個一模一樣的效果(有時候還要經過多次修改)
所以Airbnb團隊在一年前決定要在這方面做一次改變,這也是Lottie項目的由來。
通過讀取Bodymovin導出的JSON檔案,Lottie可以即時的渲染After Effect的動畫,並且使用起來就像放入圖片一樣簡單。
Lottie的目標是儘量去支持After Effect中所使用到的效果(可以看官方列出來的效果支持list)
對於Airbnb這種全球化的公司來說,他們非常需要一種可以再多平台播放且可以去適應不同設備的動畫格式,
他們有提到一些類似的開源項目,比如Marcus Eckert的Squall,Facebook的Keyframes,
不過和Lottie的目標相比,Keyframes只有支持After Effect一小部分的效果,
而Squall在Airbnb設計團隊中經常會用到,但Squall只有支持iOS。
而Lottie還支持通過網路來讀取JSON File,這也表示拿來做A/B testing會變得很方便。
目前Arirbnb團隊已經開始在產品線上通過Lottie來顯示動畫了,同時支持iOS、Android以及React Native。
幾個動畫例子
一般來說當我們的項目中出現動畫需求的時候,設計師會先幫我們準備動畫的示意圖,比如下面這三個,
剛開始我們可能都會想到使用GIF,但其實GIF的檔案不小,並且為了適配不同大小的屏幕還需要做處理。
又比如下面這三種更複雜一點的動畫,也有人想過用關鍵幀(Keyframes)動畫,也可以用上Facebook Keyframes,
但其實寫起來還是蠻花時間的。
After Effect Bodymovin
通過使用Bodymovin插件,我們可以將After Effect的動畫導出成一個JSON檔案。
設計師如果有After Effect,可以在這裡找到bodymovin的plugin和介紹
安裝之後需要在preferences中打開”Allow Scripts to Write Files and Access Network”。
而Plugin可以在window -> extensions下看到bodymovin
在bodymovin plugin介面下記得先選擇Destination Flder,然後就可以選擇render拿到文件了。
測試過程中發現如果settings勾選了除了demo以外的內容,會生成js文件,而不是可以使用的JSON文件,應該是包括了其他內容。
After Effect第一次註冊有免費使用期限,可以拿來玩看看,如果還不會做動畫也可以先拿Lottie中的幾個sample來玩(在這裡)
如果想要在線上看效果,也可以在官方文件中直接拿JSON文件來玩,其中TypeFace放的是字母的動畫。
這裡放一個可以在線上看bodymovin文件的網站。
Lottie
首先是一個最基本的使用例子,只需要給Lottie我們的bodymovin檔案名稱,他就可以讀取動畫了。
1 2 3 4 5 6 |
let animationView = LAAnimationView.animationNamed("hamburger") self.view.addSubview(animationView!) animationView?.play(completion: { (finished) in // Do Something }) |
Custom Transition例子
當present一個ViewController時,讀取”vcTransition1″動畫,dismiss時讀取”vcTransition2″動畫:
而我們所寫的code只有幾行而已。
Transition.swift檔案
1 2 3 4 5 6 7 8 9 10 11 |
class Transition: NSObject, UIViewControllerTransitioningDelegate { open func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { let animationController = LAAnimationTransitionController(animationNamed: "vcTransition1", fromLayerNamed: "outLayer", toLayerNamed: "inLayer") return animationController } open func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { let animationController = LAAnimationTransitionController(animationNamed: "vcTransition2", fromLayerNamed: "outLayer", toLayerNamed: "inLayer") return animationController } } |
AnimationTransitionViewController.swift,其中transition是Transition實例化的對象。
1 2 3 |
let VC = AnimationPresentedViewController(nibName: "AnimationPresentedViewController", bundle: nil) VC.transitioningDelegate = transition present(VC, animated: true, completion: nil) |
縮放動畫
Lottie庫還支持縮放動畫,就像使用UIImageView一樣,可以直接使用ScaleToFill,AspectFill,AspectFit之類的。
1 |
laAnimation?.contentMode = .scaleAspectFit |
打字動畫 & 跳轉到某一幀(Frame)
在官方的例子中我們看到一個更炫的效果,在打字的過程中出現的字母都是有動畫的,而且連光標(Cursor)都能有動畫!
通過設定animationProgress我們甚至可以讓動畫直接跳到某一幀。
1 |
laAnimation?.animationProgress = CGFloat(slider.value) |
Lottie沒有辦法實現的內容
Lottie是通過讀取bodymovin文件來進行動畫渲染,
所以對於變動的內容(如商品列表)產生的轉場(Transition)動畫就無法處理了。
比如下面的例子,這種transition是個不錯的UX例子,可以讓使用者很清楚目前所在的地方。
目前Lottie針對After Effects尚未支持的內容
(最後更新:2017-2-15)
- Image Layers
- Precomps
- Even-Odd winding paths
- Trim Shapes Individually feature of Trim Paths
- Expressions
- 3d Layer support
- Gradients
- Polystar shapes (Can convert to vector path as a work around)
- Alpha inverted mask
參考和推薦
- 本文中的例子,請參考我根據官方版本在Github上改寫的Swift版Lottie Example。
- Airbnb解釋為什麼要做Lottie
- 官方Objective-C版的Lottie Example
- 上面提到的,在線上來讀取bodymovin動畫的工具
- Lottie Files – 動畫素材
另外,每次打字都挑出一個文字動畫的做法還蠻有趣的,通過一個不顯示的UITextField監控輸入的內容,
然後根據輸入的內容建立UICollectionCell,而在這個Cell裡面其實就是放著LAAnimationView….真的頗有趣~!
祝大家玩得愉快~
謝啦! 這資訊很有用喔~
厉害,很详细的介绍
看了一下介绍,很赞,很喜欢。文字动画有让人眼前一亮的感觉,接下来尝试着接入项目中体验一下~ 之后再来反馈~
👍👍 个人也觉得蛮有趣的haha~
hi,你的帖子介绍的很详细,不过有一些内容可能没有介绍到。我也没有弄太明白,想向你请教一下。
lottie如何加载app内部的资源文件呢?
现在我有这样的需求,动态更新本地的动画,下载资源包后保存在cache文件夹内,如何能够通过lottie的json文件找到cache中对应的图片资源呢?
请赐教,多谢🙏
你好,其实你点进去下面的animationNamed()方法,可以看到官方的SDK提供了多种读取动画文件的方法。
watermelon = LAAnimationView.animationNamed(“Watermelon”)
open class func animationNamed(_ animationName: String!) -> Self!
open class func animation(fromJSON animationJSON: [AnyHashable : Any]!) -> Self!
public init!(contentsOf url: URL!)
所以其实App通过网路下载好动画文件后,我们可以把文件存在沙盒中,然后通过读取沙盒的文件来执行动画。
这里举一个例子:
// setup animation view
let jsonFilePath: String = NSHomeDirectory() + "/Documents/sand.json"
animationView = LAAnimationView(contentsOf: URL(fileURLWithPath: jsonFilePath))
Github上的example我已经增加了读取沙盒文件的例子,也可以下载下来看看。
感谢博主精彩的分享!
感谢你的欣赏:D