一.困境
做动画难免会有类似的经历:
Digging through frameworks for reference, guessing durations, manually creating Bézier curves, and re-making animations with nothing more than a GIF for reference
照着GIF图/效果视频去模仿,猜测动画时长,手动创建贝塞尔曲线……反复调整参数,一遍遍目测效果,最后发现:
存在很多细节差异
效果不够细腻
由于兼容性等约束,有些效果没法实现
好不容易实现了,还原度却达不到要求。通常要么设计师妥协,要么坐一起再调个半天,改到对方满意为止,结果调整细节耗费的时间比预想的多好几倍,效果还是差强人意
有经验的设计师会从AE(Adobe After Effects)中粘出一些有用的信息,比如贝塞尔曲线参数、动画时长……甚至能够提供一些实现思路,但无论怎样,照着视频实现动画就像临摹,效果差异几乎是不可避免的。仔细想想这个过程,动画对设计师来说有不小的工作量,但工程师这边似乎有更大的工作量,每个目标平台都有一份工作量,并且这些工作是一次性的,几乎无法复用并且难以维护(从几百行的并行、串行动画序列中找出某个参数,给加个0.1
)
那么,为什么一幅画完成之后还要临摹几遍呢?能否把1 + N
的工作量缩减到1 + 0.n
,同时还保证效果高度还原呢?
二.探索
既然这幅画已经完成了,就没必要从零开始手工临摹,可以利用工具从画中提取出必要的信息,再拿到目标平台用这份信息重建动画:
Now engineers can use exactly what the designer intended, exactly how it was made.
从而:
保证高还原度(直接从设计原稿取出的动画参数,一定可靠)
缩减多端的
N
份工作量(让基础动画代码可高度复用,具体效果配置化)
就像之前有经验的设计师会把动画参数粘出来一样,从设计稿中导出足够多的必要信息就能确保还原度(exactly how it was made)
有了完备的动画参数就可以进一步配置化,在目标平台解析这份配置数据,完成轨迹回放(重建动画)。各平台实现业务无关的动画基础库,业务层只需要要把配置数据输入基础库,接下来由配置数据控制动画效果、时序及其组合,这样就能把N
的业务层工作量缩减到0.n
三.目标定位
Lottie就是这样的一种方案,想要缩减多端实现动画的业务工作量(easily),同时保证动画效果高度还原(high-quality):
Easily add high-quality animation to any native app.
具体地:
Lottie is an iOS, Android, and React Native library that renders After Effects animations in real time, allowing apps to use animations as easily as they use static images.
适用于多端(iOS, Android, React Native和Web),能够轻松愉快地实现AE动画效果
Lottie allows engineers to build richer animations without the painstaking overhead of re-writing them.
跨平台的优势在于减少多端重复工作,毕竟动画效果的定义和实现是一件复杂且耗时的事情:
How difficult and time consuming it can be to re-create animations from scratch.
实际上也有类似的其它方案,比如facebookincubator/Keyframes:
A library for converting Adobe AE shape based animations to a data format and playing it back on Android and iOS devices.
Keyframes的局限性在于仅支持部分(交互响应方面的)AE特性,而Lottie的目标是支持大多数AE特性:
Our goal is to support as many After Effects features as we possibly can, to allow for a lot more than simple icon animations.
支持的AE特性越多,对设计师的约束越少,这也是Lottie方案更受欢迎的原因之一
四.实现思路
JSON
Bodymovin ----------> Lottie Player
图片资源
设计师用AE做好动画后,通过Bodymovin(AE插件)导出JSON格式的Lottie动画定义及相关图片资源,输出给Android、iOS、ReactNative、Web前端工程师,工程师调用对应平台的Lottie Player加载动画资源,并控制动画播放/暂停等
AE插件部分负责把AE的动画定义转换成Lottie动画定义,并输出JSON文件,难点在于支持转换更多的AE特性,以免设计师用起来束手束脚
播放器部分负责解析Lottie动画定义,加载相关资源并利用平台支持的技术实现动画效果,比如Web环境下默认通过SVG动画来实现,可选Canvas绘制和CSS动画实现
关键在于:
通用的动画定义
各平台下支持该动画定义的播放器
类似于Java的跨平台思路:平台无关的class文件 + 平台相关的JVM实现
五.lottie-web
airbnb/lottie-web是Web环境的Lottie Player,简单的几行代码就能实现复杂的动画效果,例如:
<div id="bm"> </div>
var animation = bodymovin.loadAnimation({
container: document.getElementById('bm'),
renderer: 'svg',
loop: true,
autoplay: true,
path: 'data.json'
})
P.S.具体效果见Simple Bodymovin Demo
默认通过SVG实现(renderer: 'svg'
),另外还支持canvas
和html
,区别在于:
svg
:动画元素(形状等)用SVG实现,动画效果通过SVG动画来做canvas
:通过元素用Canvas绘制,动画效果通过rAF
定时刷新重绘来实现html
:动画元素用SVG实现,动画效果通过CSS动画来做
实际使用中发现,SVG模式兼容性最好,HTML模式下遮罩动画存在圆角放大变方的问题
P.S.关于SVG及其动画,请查看SVG基础知识
P.S.更多详细API见Usage
引入lottie-web有两种方式,要么引CDN资源,要么下载最新release:
$ ls lottie-web-5.3.0/build/player/
lottie.js lottie.min.js lottie_light.js lottie_light.min.js
其中,lottie_light.js
(轻量版)仅支持SVG模式,且不支持expressions
六.总结
Rax的跨容器运行、Lottie的跨端动画……前端技术方案已经不再局限于前端领域,而是往上下游扩展,拉着设计师、客户端兄弟、服务哥哥一起玩,比如:
Ant Design:前端 + 设计师
React Native:前端 + 客户端兄弟
Backends For Frontends:前端 + 服务哥哥
通过上下游的横向碰撞,沉淀产出能够提高整体效率的方案,似乎成了一种必然趋势
123