Lottie - 设计和实现高性能动画效果

Lottie 介绍

Lottie 是 Airbnb 开源的一套跨平台的完整的动画效果解决方案,提供了专注于实现跨平台的高性能动画效果的 lottie-web、lottie-android、lottie-ios 产品,也提供了面向UI设计师和开发工程师的动画创作平台和其他创作平台的转化插件。

在 Lottie 出现之前,页面如果要展示酷炫的动画效果,开发者往往只能选择以下两种方式。

  • 动图
    设计师导出 GIF 等格式的动图,这类动图往往体积很大,加载体验差;其次难以控制,无法控制启动暂停时机,进而多多动画效果无法协作。
  • CSS实现
    开发者基于设计师提供Layer素材,利用 CSS 特效高仿出动画效果。这个是比较常见的,性能也能得到保证,但是无法实现复杂的动画效果,多动画效果之间的协作难以控制。
  • JavaScript 实现
    对于一些复杂的动画,开发者基于对动画的理解,采用 JavaScript 直接控制页面元素模拟动画效果,例如 Canvas、HTML 元素。这类实现往往是以牺牲性能为代价,无法跨平台使用,且实现及其复杂。

开发者和设计师迫切的需要一款产品,首先是将设计师视角下的动画效果(AE设计)转化成开发者能够使用的数据形式,降低沟通成本;其次是实现动画效果的高性能展示,并且提供一定程度的控制能力。

Lottie 就是在这种场景下应运而生的,设计师使用AE等设计工作设计出酷炫的效果,经过BodMoveIn插件导出 Json 文件,开发者根据业务需要填充业务数据,主要是更换素材,借助 lottie-web、lottie-android、lottie-ios 组件进行展示和控制动画效果。

Lottie 并不是一个最近出现的产品,业内也是一直在广泛的应用。近些年 Lottie 更多的是在动画创作方面做出的巨大的努力,一方面提供更多的转化插件,支持 AE、Figma、Sketch 等主流UE、UI设计产品的转换工具。

另外一方面则是设计了 Lottie Creator 的网页创作工具,支持开发者也能够自行设计酷炫的动画效果;

也提供了 LottieFiles 协作者平台,实现设计者之间的作品管理与共享;这些创新可以给我们带来意想不到的爽感,这也是本文重点向大家介绍的内容。

Lottie 使用

以 Lottie-web 为例,其使用十分简单。

初始化

php 复制代码
const anim = lottie.loadAnimation({
  // path: animJsonPath, // 动画json文件路径
  animationData: animationJSON,
  renderer: 'svg',
  loop: true,
  autoplay: true,
  container: lottieRef.current,
});

动画控制API

scss 复制代码
anim.play(); // 播放动画,从目前停止的帧开始播放
anim.stop(); // 停止播放动画,回到第0帧
anim.pause(); // 暂停动画,在当前帧停止并保持

anim.goToAndStop(value, isFrame); // 跳到某个时刻/帧并停止。isFrame(默认false)指示value表示帧还是时间(毫秒)
anim.goToAndPlay(value, isFrame); // 跳到某个时刻/帧并进行播放
anim.goToAndStop(20, true); // 跳转到第20帧并停止
anim.goToAndPlay(200); // 跳转到第200毫秒并播放

anim.playSegments(arr, forceFlag); // arr可以包含两个数字或者两个数字组成的数组,forceFlag表示是否立即强制播放该片段
anim.playSegments([10,30], false); // 播放完之前的片段,播放10-30帧
anim.playSegments([[0,10],[20,30]], true); // 直接播放0-10帧和20-30帧

anim.setSpeed(speed); // 设置播放速度,speed为1表示正常速度
anim.setDirection(direction); // 设置播放方向,1表示正向播放,-1表示反向播放
anim.destroy(); // 销毁动画,移除相应的元素标签等。在unmount的时候,需要调用该方法

常用事件

Lottie-web 还可以对动画的常规事件进行监听。

ini 复制代码
anim.addEventListener('DOMLoaded', () => {
  if (typeof callback === 'function') {
    callback(anim); // 处理动画内交互逻辑
  }
});

除了DOMLoaded事件,下面还有一些其他常用的事件可以监听:

  • complete: 播放完成(循环播放下不会触发)
  • loopComplete: 当前循环下播放(循环播放/非循环播放)结束时触发
  • enterFrame: 每进入一帧就会触发,播放时每一帧都会触发一次,stop 方法也会触发
  • segmentStart: 播放指定片段时触发,playSegments、resetSegments 等方法刚开始播放指定片段时会发出,如果 playSegments 播放多个片段,多个片段最开始都会触发。
  • data_ready: 动画 json 文件加载完毕触发
  • DOMLoaded: 动画相关的 dom 已经被添加到 html 后触发
  • destroy: 将在动画删除时触发

数据格式

当先很多动画效果并不是一成不变的,而是依据客户动态生成的。如果是要设计师为每个场景都设计一套效果数据,很明显是不显示的。好在 LottieData 是 JSON 格式的,只要能够理解其数据格式,开发者就可以自行调整一些动画效果,进行复用。

本文提供一个比较经典的动画效果-若干头像流星滑落的效果,JSON源文件-GitHub,动画效果请自行体验。

第一层数据结构主要是定义动画的整体控制信息。

json 复制代码
{
  "v": "5.6.7", // bodymovin 版本
  "fr": 30, // 帧率
  "ip": 0, // 起始关键帧
  "op": 736, // 结束关键帧
  "w": 612, // 视图宽
  "h": 198,  // 视图高
  "nm": "Avatars Lottie无蒙版", // 名称
  "ddd": 0, // 是否为3d
  "assets": [], // 资源集合 
  "layers": [], // 图层集合(包含动画中的每一个图层和动作信息)
  "markers": [], // 蒙层集合
}

这里 fr、ip、op、layers、assets是实际应用中可能需要关注的,特别是前 3 个尤为重要。

下面是图层数据格式,以复用为目标的场景下,只需要改动图层的部分数据和 assets 的部分资源信息即可,轨迹层面的改动需要关注 ks 图层变化属性,也是基于 CSS 效果来实现的,仅仅是描述语言不同,本质是一样的。

json 复制代码
"ddd": 0,                   // 是否为3d
"ind": 15,                  // layer的ID,唯一
"ty": 2,                    // 图层类型 
"nm": "light /新的.psd",    // 图层名称
"cl": "psd",
"parent": 32,
"refId": "image_0",
"sr": 1,
"ks": {                             //变换。对应AE中的变换设置

  "o": { "a": 0, "k": 100, "ix": 11 },     // 透明度
  "r": {...},                              // 旋转
  "p": {... },                             // 位置
  "a": {...},                              // 锚点
  "s": {                                   // scale 缩放
    "a": 1,
    "k": [
      {
        "i": { "x": [0.48, 0.48, 0.48], "y": [1, 1, 1] },
        "o": { "x": [0.26, 0.26, 0.26], "y": [1.01, 1.01, 0] },
        "t": 7,              // 代表关键帧数 (0-7帧 ,前后的变化)
        "s": [0, 0, 100],    // 代表变化前(图层为二维)。
        "e": [99, 99, 100]   // 代表变化后(图层为二维)。
      },
       {
        "i": { "x": [0.833, 0.833, 0.833], "y": [1, 1, 1] },
        "o": { "x": [0.167, 0.167, 0.167], "y": [0, 0, 0] },
        "t": 18,
        "s": [99, 99, 100],
        "e": [99, 99, 100]
      },
     ]
    },                             
},
shapes:[...],   //图层的宽高信息
"ao": 0,
"ip": 0,
"op": 150,
"st": 0,
"bm": 0

该数据格式相对于传统 Gif 格式,体积能够压缩到1/6,如上图所示,其新格式 dotLottie 在 JSON 的基础上再压缩到 1/6,数据体积大大降低。

渲染原理

LottieComposition 负责将 json 文件解析成数据对象, LottieDrawable 负责将 LottieComposition 解析的对象 绘制成 drawable 显示在 View 上。其底层绘制调用的是 Canvas 和 SVG 的API,这里就不详细介绍了。

LottieFiles 社区

LottieFiles 社区是最大的 Lottie 交流社区,主要服务于设计师和开发者,类似花瓣这类创作者网站。其本身属于其商业化的一部分,会有一些付费的功能和动画设计共享。对于我们开发者来说比较有用的部分是提供了 Lottie Creator 的动画效果网页编辑器,其使用比较傻瓜。这对于开发者是个福音,毕竟开发者对于 AE 等工具上手难度还是有的。

Lottie Creator 在线编辑器

上图是 Lottie Creator 的主要面板,且设计方式十分类似PPT的制作方式,其门槛并不高。开发者选择各种动效之后动画效果会自动拆解到每秒30帧,然后每帧进行微调。

我对这个编辑器的未来还是蛮看好的,当先就体验而言还是存在很多不足的,首先是性能问题,复杂效果之后卡顿明显;其次 AE Plugin 导出的 JSON 能够导入,但并不能编辑,大概率这个编辑器是个阉割版,无法支持复杂动画效果的编辑。

支持工具

数据转化

官网支持了 GIF、MP4、WebM、MOV 数据导出,虽然导出很慢,但是还是勉强能用。我推测其可能是采用的录制方式实现的,因此性能开销比较大。

调色板

支持对 SVG 素材进行微调色值,提供一系列调色板色系。

相关推荐
M_emory_23 分钟前
解决 git clone 出现:Failed to connect to 127.0.0.1 port 1080: Connection refused 错误
前端·vue.js·git
Ciito26 分钟前
vue项目使用eslint+prettier管理项目格式化
前端·javascript·vue.js
成都被卷死的程序员1 小时前
响应式网页设计--html
前端·html
mon_star°1 小时前
将答题成绩排行榜数据通过前端生成excel的方式实现导出下载功能
前端·excel
Zrf21913184551 小时前
前端笔试中oj算法题的解法模版
前端·readline·oj算法
文军的烹饪实验室3 小时前
ValueError: Circular reference detected
开发语言·前端·javascript
Martin -Tang4 小时前
vite和webpack的区别
前端·webpack·node.js·vite
迷途小码农零零发4 小时前
解锁微前端的优秀库
前端
王解4 小时前
webpack loader全解析,从入门到精通(10)
前端·webpack·node.js
我不当帕鲁谁当帕鲁5 小时前
arcgis for js实现FeatureLayer图层弹窗展示所有field字段
前端·javascript·arcgis