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

其中有个营销活动(领红包)的弹窗动画就要用到 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

小程序中使用 lottie 动画 | 踩坑经验分享的更多相关文章

  1. 微信小程序中scroll-view的几个坑

    微信小程序中scroll-view的几个坑 1:设置scroll-x时,却不能横向滚动,因为view是block组件,但是这里用了flex就不能滚动了(想用flex布局,请开启属性enable-fle ...

  2. 小程序中搜索文件,阅览pdf,分享文件链接,评论表情符号

    小程序中搜索文件,阅览pdf,分享文件链接,评论表情符号 https://blog.csdn.net/hotqin888/article/details/84111389 小程序中打开网页和pdf h ...

  3. 微信小程序使用pako.js的踩坑笔记

    问题 今天组长跟我们讨论了个问题,说是文章存储占用有点大,消耗宽带流量费,让我看看能不能找个方法解决一下(文章存储的是html字符串).第一反应是没什么头绪,能想到的就是将相同的字符串替换成一个标识之 ...

  4. 微信小程序使用weui扩展组件踩坑

    最近在做微信小程序,引入weui的时候踩坑了好久,这里记录一下遇到的问题. 微信官方文档给了两种weui引入方式: 通过 useExtendedLib 扩展库 的方式引入,这种方式引入的组件将不会计入 ...

  5. 微信小程序 请求签名接口超时 踩坑路。。

    我们公司一般做开发都是先用测试机的接口调试功能,等功能都调试的差不多了,再换成线上的正式接口,因为正式接口要验证签名. 这几个功能都调试的差不多了,准备换成线上正式接口了,结果却出了问题,提示请求超时 ...

  6. 微信小程序豆瓣电影项目的改造过程经验分享

    在学习微信小程序开发过程中,一部分的难点是前端逻辑的处理,也就是对前端JS的代码编辑:一部分的难点是前端界面的设计展示:本篇随笔基于一个豆瓣电影接口的小程序开源项目进行重新调整,把其中遇到的相关难点和 ...

  7. 微信小程序中实现微信支付

    最近在做微信小程序,今天刚好做到小程序里的微信支付这块,踩过不少坑,特此写个博客记录下,希望能帮到其它人吧. 我总结了一下,小程序中的微信支付和之前其它的公众号里的微信支付有两个区别,第一就是小程序必 ...

  8. 微信小程序中事件

    微信小程序中事件 一.常见的事件有 类型 触发条件 最低版本 touchstart 手指触摸动作开始 touchmove 手指触摸后移动 touchcancel 手指触摸动作被打断,如来电提醒,弹窗 ...

  9. 在微信小程序中绘制图表(part2)

    本期大纲 1.确定纵坐标的范围并绘制 2.根据真实数据绘制折线 相关阅读:在微信小程序中绘制图表(part1)在微信小程序中绘制图表(part3) 关注我的 github 项目 查看完整代码. 确定纵 ...

  10. 网页或微信小程序中使元素占满整个屏幕高度

    在项目中经常要用到一个容器元素占满屏幕高度和宽度,然后再在这个容器元素里放置其他元素. 宽度很简单就是width:100% 但是高度呢,我们知道的是height:100%必须是在父元素的高度给定了的情 ...

随机推荐

  1. 【问题解决1】fatal error: X11/XXXX.h: No such file or directory

    问题现象 编译鸿蒙代码时,报如下类似的错误: 错误1: 错误2: 解决方法 step 1:安装依赖文件 sudo apt-get install apt-file sudo apt-file upda ...

  2. Web、Android等程序开发中src引入外部文件和资源的方法总结

    方法一:使用相对于当前文件(源文件)的相对路径 使用 ../ 对于这个例子来说 ../ 把路径带到了项目根目录的下一级目录 1 <script src="../static/js/wo ...

  3. Python爬虫初步---jupyterNptebook使用

    学习视频笔记:

  4. 到底什么是AQS?面试时你能说明白吗!

    写在开头 上篇文章写到CAS算法时,里面使用AtomicInteger举例说明,这个类在java.unit.concurrent.atomic包中,存储的都是一些原子类,除此之外,"java ...

  5. #斜率优化,二分#CF631E Product Sum

    题目 有一个数列 \(a\),其权值为 \(\sum_{i=1}^ni*a_i\), 现在可以任意选择其中一个数字扔到任意位置,使权值和最大. \(n\leq 2*10^5,|a_i|\leq 10^ ...

  6. HDC2021技术分论坛:ArkUI 3.0让多设备开发更简单!

    作者:wanglei,华为UI编程框架技术专家 HarmonyOS自诞生以来,就是为满足分布式多设备应用场景而设计的,大到智慧屏.车机.平板,小到手机.手表.在多设备场景下进行应用UI界面开发,面临新 ...

  7. 一文带你详细了解HarmonyOS折叠屏设计规范!

    原文:https://mp.weixin.qq.com/s/G25IbfcX2Bq9s1IDPCELGw,点击链接查看更多技术内容. 随着新一代折叠屏手机HUAWEI Mate Xs 2发布,Harm ...

  8. Avalonia 中的样式和控件主题

    在 Avalonia 中,样式是定义控件外观的一种方式,而控件主题则是一组样式和资源,用于定义应用程序的整体外观和感觉.本文将深入探讨这些概念,并提供示例代码以帮助您更好地理解它们. 样式是什么? 样 ...

  9. Kafka 集群副本数量调整

    Kafka 创建时未指定多个副本或者副本数量过少,都可以在后期手动添加,另外如果副本过多也可以减少,当前调整基于 Kafka 的版本是 2.5.1,但是估计 2.1 ~ 2.5 应该都是兼容的. 下面 ...

  10. HL7消息类型

    HL7消息有很多不同的类型,每种都有其自己的独特用途和消息内容.以下是常见的HL7消息类型的列表. Message Type Description HL7 ADT Admit, Discharge ...