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

其中有个营销活动(领红包)的弹窗动画就要用到 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. 任何样式,javascript都可以操作,让你所向披靡

    前言 习惯了在 css 文件里面编写样式,其实JavaScript 的 CSS对象模型也提供了强大的样式操作能力, 那就随文章一起看看,有多少能力是你不知道的吧. 样式来源 客从八方来, 样式呢, 样 ...

  2. node-xlsx处理excel

    引用node-xlsx npm install node-xlsx -save 文件中引用 const xlsx = require('node-xlsx') 读取excel const sheet ...

  3. Boruta特征选择

    Boruta特征选择 官方github地址:https://github.com/scikit-learn-contrib/boruta_py?tab=readme-ov-file 论文地址:http ...

  4. 【Jenkins】Jenkins 运行权限问题

    yum安装的Jenkins 配置文件默认位置/etc/sysconfig/jenkins 默认jenkins服务以jenkins用户运行,这时在jenkins执行maven脚本时可能会发生没有权限操作 ...

  5. SpringBoot项目 填充Excel模板 导出 下载

    模板 下载后的效果 项目结构 pom <?xml version="1.0" encoding="UTF-8"?> <project xmln ...

  6. 第一次画pcb学到的知识

    第一次画pcb学到的知识 1. Typec (6针) 其中的CC1.CC2引脚为快充协议的引脚,用不到的时候串个5.1K的电阻接地s 2. AMS117降压电路 AMS1117芯片的输入电压都要一个1 ...

  7. Scala打印输出

    1 package com.atguigu.chapter02 2 object TestCharType { 3 def main(args: Array[String]): Unit = { 4 ...

  8. MySQL检索和过滤数据

    注意 多条SQL语句必须以分号(:)分隔: SQL语句不区分大小写: 在处理SQL语句时,其中所有空格都被忽略: 当选择多个列是,一定要在列名之间加上逗号,但最后一个列名后不加. SELECT语句 检 ...

  9. #组合计数,全排列#洛谷 2518 [HAOI2010]计数

    题目 你有一组非零数字(不一定唯一),你可以在其中插入任意个0,这样就可以产生无限个数. 比如说给定{1,2},那么可以生成数字12,21,102,120,201,210,1002,1020,等等. ...

  10. 巴延兴:从主导多个SIG组到OpenHarmony“代码贡献之星”,我是如何做到的?

    编者按:在 OpenHarmony 生态发展过程中,涌现了大批优秀的代码贡献者,本专题旨在表彰贡献.分享经验,文中内容来自嘉宾访谈,不代表 OpenHarmony 工作委员会观点. 巴延兴 深圳开鸿数 ...