lottie动画_Aha Lottie | 用 async/await 优雅地控制 Lottie 播放

dbb02fa351fc4587a582c0d4c1815719.png

01. Lottie 的播放控制 API


Lottie 最大的特点是提供了一系列 API 来控制动画播放,从官方文档可以看到这几个主要 API

  • play()
  • playSegments()
  • pause() / resume()
  • setSpeed()


除了一看就懂的开始、暂停、调整播放速度之外,有一个奇妙的 playSegments 方法,它可以指定只播放 Lottie 动画中的一小段

animation
  • 第一个参数是数组,指定了播放帧区间,比如上面例子指从第 10 帧播放到第 20 帧
  • 第二个参数表示是否强制播放,如果当前 lottie 动画已经在播放的话,这个参数设为 true 可以先强制停止之前的动画后,再播放指定的帧区间


别小看这么简单一个 API,正是通过它我们才能实现各种复杂的业务

02. 简单例子


找一个简单的例子看下,这里有一个来自社区 lottie 文件 , 一共 240 帧,可以看到动画中有多种车型的 loading

895961b1fb69edd62bce90414304375b.png
LottieFile 上的截图
  • 0~36 帧是小汽车
  • 37~72 帧是跑车
  • ……
  • 180~206 是公交车
  • ……


现在如果只需要播放公交车那段 loading 的话,用 playSegments 很容易实现

const 


这里有几个常见坑点

  • 记得在 lottie 动画 DOMLoaded 之后再调用 playSegments,否则会播放完整段动画后才播放片段,这可以说是 lottie 实现的一个小 bug,但也是新手最常遇到的问题
  • 动画是否循环由初始化动画时的 loop 属性决定,如果初始化时设为 false,那么 playSegements 的片段只会播放一遍
  • 可以在播放前通过 animation.loop = true 再设置,不过这个属性不见于官方文档


实际效果是这样

6da91eb833fbe5c043d9005812162bf8.png
只播放公交车动画https://www.zhihu.com/video/1197140333916434432


代码参考

distracted-hill-c2fyr - CodeSandbox​codesandbox.io
384e1fed8e622e0ff4a8b407c57c0c72.png


03. 复杂例子


如果只是这么简单的例子,那全文就到此结束啦,下面看个复杂的例子,上一篇文章中有一个掷骰子的动画

f0fa1a96fa3719a06af51f4ba83350e5.png
掷骰子动画https://www.zhihu.com/video/1197140754982670336


这段 Lottie 其实长这样

9aab2de1d9f02bfd5e9321b95204b282.png
掷骰子 Lottiehttps://www.zhihu.com/video/1197141036710133760
  • 0~25 帧是骰子从左下角抛出
  • 26~35 帧是骰子在空中旋转
  • 36~39 帧是骰子 1 点(一共 4 帧)
  • 40~43 帧是骰子 2 点(一共 4 帧)
  • ……


做过营销页的前端都知道,这里通常会伴随着一个 ajax 请求去获取应该掷出几点,大致流程是

  1. 发起 ajax 请求,同时播放骰子 掷出的动画
  2. ajax 请求返回后,播放相应点数的动画


代码撸起

btn


这样一下就看出 lottie 的潜力了,不仅仅是播放动画那么简单,还能结合业务实现一些逻辑呢!
上面的实现看起来很简单,但是仔细思考一下就会发现不少问题

  • ajax 如果耗时很短,那么骰子刚抛出一半就展示结果,体验不太好(其实是太假了 )
  • ajax 如果耗时很长,那么就更尴尬了,要么一直 loop 播放骰子抛出来,要么动画停在原地不动


可以查看这段代码感受一下

cocky-currying-djgbg - CodeSandbox​codesandbox.io
6aac6445312bf10e3080327309ac0611.png


03.1 体验优化


仔细思考下体验的优化,其实需要对动画+异步 ajax 做比较精细的操作,如下

  • 并发骰子抛出 + ajax 请求
  • 保证骰子抛出 + 空中旋转至少播放一次,之后再展示点数,应对 ajax 耗时短的情况
  • 空中旋转可以循环播放,应对 ajax 耗时长的情况

1471cbe0b90159c37f8c802d4f572232.png
动画 + ajax 的异步流程


为了实现这个上面的效果,我们需要感知一段动画播放结束,这在 lottie 中有 complete 事件
先简单尝试下,在筛子动画播放完成后再展示点数

animation


这里可以发现,通过事件监听方式来做会比较麻烦,需要设置不少临时的中间变量,另外以上代码离最终目标还有不少差距,比如没实现循环播放

04. 优雅地控制播放


那么如何优雅地写出复杂的播放控制代码呢?
仔细思考一下,这个案例本质上是异步流的控制,于是我们可以引入 Promise
首先将播放动画这个过程,封装为 Promise

function 


这里用到一个 lottie 文档未说明的技巧,addEventListener 的返回值是一个函数,用于移除事件监听
基于上面这个 Promise 封装,结合 async/await 很多场景的代码就变得优雅多了
比如,先后播放两段动画,并且在播放完成之后做一些事情

await 


不满足条件时,一直循环播放某一段动画,这样就不依赖于初始化动画时的 loop 参数了

while


ajax 与动画同时发生,当动画播放完毕,并且 ajax 返回时进入下一个环节

const 


04.1 完整实现


于是再回到上面的例子,我们可以写出优雅的播放控制代码了

// 播放掷骰子的动画


完整代码参考

weathered-fire-ysnhz - CodeSandbox​codesandbox.io
8c3a8d88f8706873592d2910f42588ef.png


04.2 小结


通过 lottie 事件,将动画播放过程封装为 Promise 之后,就可以对接进入各种异步流管理中了,不论是顺序、并发还是上面更复杂的例子,代码写起来都很优雅,适合纳入最佳实践
最后是下篇预告:

Chaos:Aha Lottie | 动态修改 Lottie 中的文本​zhuanlan.zhihu.com
d7d6a24961be4ca2727417e37e562fbf.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值