当前位置: 首页 > 资讯中心 > 游戏攻略 > 在小程序中使用lottie动画遇到的问题与解决办法

在小程序中使用lottie动画遇到的问题与解决办法

来源:网络作者:提莫时间:2024-04-29 19:01:44
分享到:
标签:
最近被拉去支援紧急需求(赶在五一节假日前上线的,双休需要加班😱),参与到项目中才知道,开发的项目是微信小程序技术栈的。由于是临时支援,笔者也很久没开发过微信小程序了,所以挑选了相对独立,业务属性相对轻薄的模块参与。 其中有个营销活动(领红包🧧😁)的弹窗

最近被拉去支援紧急需求(赶在五一节假日前上线的,双休需要加班?),参与到项目中才知道,开发的项目是微信小程序技术栈的。由于是临时支援,笔者也很久没开发过微信小程序了,所以挑选了相对独立,业务属性相对轻薄的模块参与。

其中有个营销活动(领红包??)的弹窗动画就要用到 lottie 动画。

本文就分享一下在小程序中使用 lottie 过程中遇到的问题与解决办法。

关于 lottie

lottie是Airbnb开源的一个动画库,用于在端上直接播放AE (Adobe After Effects)动画。

通过bodymovin AE 插件将动画文件导出为json文件,lottie SDK 可以通过JSON文件直接播放动画。

具体 demos 效果可以上LottieFiles网站查看。

如何使用AE导出动画需要的JSON文件

完成AE软件安装后,参照Lottie Web GitHub官方文档完成 bodymovin 插件的安装。

打开动画文件后,只需简单几步操作

① window中选择Bodymovie

② 选择需要导出的动画资源

③ 导出配置(小程序相关)

点击对应动画的设置

勾选 Glyphs 将用到的文字+字体导出为图形。

小程序里渲染不支持加载外部字体。

这个就会有 tree shake的效果,如果动画里没有用到的文字,做动态替换的时候就会不显示,后面会详细介绍到。

勾选 Convert expressions to keyframes 将表达式转为关键帧,因为小程序里不支持使用 eval 等动态执行脚本的能力。

修改完成后点击 Save 保存配置。

④ 渲染导出 JSON 文件

最后点击Render按钮,导出JSON文件。

导出文件如下,data.json文件就是我们需要的JSON文件,images里存储的就是播放要用到的图片文件。

小程序中使用

可以使用小程序官方封装的lottie-miniprogram库。

快速验证的话可以打开微信开发者工具,在点击??demo代码片段进行创建。

① 安装依赖

npm install --save lottie-miniprogram

② 使用

tip:开发者工具中验证的话,渲染模式需要选择webview,Skyline目前还不支持调试canvas

index.wxml

<canvas id="lottie-canvas" type="2d"></canvas>

index.js

import lottie from 'lottie-miniprogram'

Page({
  onReady() {
    this.createSelectorQuery().select('#lottie-canvas').node((res) => {
      // 取得 canvas 节点
      const canvas = res[0].node

      // 设置 cavnas 画布尺寸
      canvas.width = 600
      canvas.height = 600

      lottie.setup(canvas)

      const context = canvas.getContext('2d')
      const lottieInstance = lottie.loadAnimation({
        loop: true, // 循环播放
        autoplay: true, // 自动播放
        // 本地使用 http-server 启动服务后,指定本地资源地址
        path: 'http://127.0.0.1:8080/lottie-demo-sources/data.json', // 通过http 制定json资源路径

        // 也可以用下面这种方式,直接传入 lottie json内容
        // (需要动态替换文案就需要用到这种方式)
        // animationData: {/* lottie json 格式内容 */},
        // 静态资源目录,通常与 animationData 配合使用
        // assetsPath: 'http://127.0.0.1:8080/lottie-demo-sources/images/',

        rendererSettings: {
          context,
        },
      })
    }).exec()
  }
})

我这个demo的效果(网上找的动画素材)如下。

问题&解决

下面介绍在实际业务接入使用中遇到的一些问题和解决办法。

expression 表达式

报错信息如下,这是遇到的第一个问题(也是上面导出配置中有特别说明的)。

细看了一下文档,有特别说明,expression表达式特性是不支持的,因此需要再导出JSON文件时禁用相关特性。

解决办法:导出JSON文件时,禁用掉表达式特性即可。

当然禁用后,JSON文件大小会有所增加。

比如我这个demo从40kb增加到了240kb(当然动画不一样,增长的大小会有所不同。有些前后可能只有1-2kb的变化)。

模糊

由于需要全屏展示,动画文件的尺寸不确定,手动只设置canvas尺寸会有模糊的问题。

这个通过掘金搜索了一下就得到了lottie动画模糊问题的解决方法。

微调一下上面的代码,就可以解决模糊问题。

const canvas = res[0].node
canvas.width = 600
canvas.height = 600

// 下面是新增的代码
const dpr = wx.getSystemInfoSync().pixelRatio
canvas.width = canvas.width * dpr
canvas.height = canvas.height * dpr
context.scale(dpr, dpr)

lottie.setup(canvas)

全屏动画

弹窗的动画需要全屏展示,因此需要设置 canvas 宽高为页面宽高。

index.wxss

#lottie-canvas{
    position: fixed;
    left: 0;
    top: 0;
    width: 100vw;
    height: 100vh;
}

index.js,使用 wx.getSystemInfoSync 获取设备的信息

const { windowWidth, windowHeight, pixelRatio } = wx.getSystemInfoSync()
canvas.width = windowWidth * pixelRatio
canvas.height = windowHeight * pixelRatio

动态文案

由于是红包,需要动态展示金额(当然也可能是不固定内容的动态标题)。

思路可以参考这篇文章知乎:动态修改Lottie中的文本。

可以使用固定格式的文本 ${文本} 进行替换

// 伪代码
get('sourceUrl').then((res) => {
  const jsonText = res.data
  const animationData = JSON.parse(jsonText.replace('${金额}', '目标金额'))
})

比如我在demo里加一个文字

  • 需要展示的文本里放入 ${num} 用于替换匹配
  • 在添加一个文本藏在看不见的地方,里面写入替换后需要用到的文字(确保和上面的文本为同一种字体)

接着导出JSON文件。

调用方法如下

// 拉取JSON文件内容
const jsonData = await new Promise((resolve) => {
  wx.request({
    url: 'http://127.0.0.1:8080/json/text-replace/data.json',
    success: (res) => {
      resolve(res.data)
    }
  })
})

// 随机生成1-100元的数字,保留两位小数
const num = (Math.random() * 100).toFixed(2)
// 替换内容
const animationData = JSON.parse(
  JSON.stringify(jsonData)
    .replace(/\$\{num\}/g, `${num}元`)
)

lottie.loadAnimation({
  // 指定json内容
  animationData,
  // 设置依赖的图片资源位置
  assetsPath: 'http://127.0.0.1:8080/json/text-replace/images/',
  // ...省略其它配置
})

效果如下

style 引发的渲染错误

在canvas标签上设置 display 控制显隐,偶现会提示渲染层错误。

<canvas style="display:{{show?'block':'none'}}" id="c1" type="2d"></canvas>

解决办法,给套了一层 view ,用 wx:if 控制咯。

<view  wx:if="{{show}}">
  <canvas id="c1" type="2d"></canvas>
</view>

iOS 播放闪退问题

现象是,非冷启动小程序的时候,动画还没播放完毕就提前结束了。

看代码log,3s的动画,播放不到 1s 就触发了 complete 事件,看现象就是一闪而逝。

const ani = lottie.loadAnimation({
  // 3s 的动画
  animationData,
  // ...省略其它配置
})

ani.addEventListener('complete', () => {
  console.log('动画播放结束')
})

解决办法

TODO:未完待续

最后

时间匆忙,介绍的不是非常的详细,感兴趣的同学可以评论区交流。

demo 完整源码见GitHub:lottie-demo

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。

相关阅读

装机必备软件
  • 下载总排行
  • 下载月排行

1高德地图2021

新闻资讯

2大众点评

聊天社交

3迅雷

壁纸主题

4一波语音

聊天社交

5知乎

摄影摄像

6映客

学习教育

7花小猪打车

学习教育

8哈啰出行最新版

聊天社交

9qq邮箱

摄影摄像

10生辰

生活健康