由于项目上,需要在小程序上,实现一些动画效果,反馈用户操作。
最初的方案,是采用GIF,但发现有一些不好的用户使用体验,即:
- GIF是自动循环播放的,无法与用户操作保持很好的同步反馈;
- GIF文件体积太大,对于低网速手机用户,加载效果不好;
问了AI,提议使用 LOTTIE ,于是,开启了踩坑之路。
大多数在微信小程序上,使用 LOTTIE ,都是从 npm install lottie-miniprogram 开始。但 lottie-miniprogram 内部依赖了 lottie-web,而 lottie-web 是使用动态创建组件的特性,而微信小程序是禁用此特性的。
因此,大多数情况下,从官网下载的demo,在微信开发者工具上,一跑,可以显示 LOTTIE 动画,但是跑到真机上,调试,就出不来了。而且在控制台会看到提示“发现 Lottie 动态创建 canvas 组件,但小程序不支持动态创建组件,接下来可能会出现异常”。
很显然,要对 lottie-miniprogram 做一下兼容处理,于是,创造轮子,不如找轮子。问了 AI,说是可以用 uniapp 的插件:c-lottie 。
https://ext.dcloud.net.cn/plugin?id=11085
感谢作者,示例写的也比较规范,清晰。试跑了一下,DEMO果然可以跑在苹果手机和安卓手机。
于是,将手头几个现成的 GIF 动画,转成 LOTTIE.json ,一开始是通过 lottiefiles 官网转换,但它只能免费转换5次,明显不够用。
将 GIF 转成 LOTTIE.json 后,实测又发现以下问题:
- 通过 lottiefiles 官网默认转换的 JSON 文件,体积竟然比 GIF 还大(无法接受!);
- 转换后的 LOTTIE.json 文件,在苹果微信上,可以正常显示动画,但在安卓微信上,跑了,显示空白;
于是,反复对比,发现,默认转换后的 JSON 文件里,图片文件的base64编码格式是 WEBP 的。秒懂,果断将图片重新编码为 PNG的base64格式,重新保存为 LOTTIE.json 文件,目前,安卓微信和苹果微信,都可以正常显示动画了。

总结:
- 要在微信小程序上,显示 LOTTIE 动画,提议直接用 uniapp 的 c-lottie 插件;
- 手头如果有现成 GIF 文件,需要转换成 LOTTIE.json ,不提议用官网 lottiefiles,改用 python库( pip3 install lottie )来转换,性价比会更容易接受;
- 通过 python-lottie 转换的 LOTTIE.json 文件,里面的 “layers” 节点的 “ip” “op” 参数,可能会不连续帧(出现跳跃),需要手工修正,保存一下(不处理的话,也看不出来,就是不好通过代码控制播放速度和帧,如果需要暂停的话)。

- 转换后的 LOTTIE.json 文件,需要确保里面的图片编码为 PNG-base64 的(可以思考通过 omggif js库,提取 GIF 文件中的图片帧,然后另存为 PNG 图片);
- 可以对 PNG文件压缩一下, 再base64(可以思考通过 sharp js库,压缩 PNG 图片);
参考代码段
///////////////////////////////////////////
将 GIF 中的图片帧,另存为 PNG 格式
// b. 使用pngjs将RGBA像素编码为PNG二进制
const png = new PNG({
width,
height,
inputColorType: 6, // 6表明RGBA格式(对应pngjs的colorType)
inputHasAlpha: true
});
// 将pixels(Uint8Array)复制到png的数据缓冲区
png.data.set(pixels);
// c. 将PNG数据转为Buffer,再转为Base64
const pngBuffer = PNG.sync.write(png); // 同步生成PNG的Buffer
///////////////////////////////////////////
压缩 PNG
// 2. 直接将 Buffer 传入 sharp() 构造处理对象
const compressedBuffer = await sharp(pngBuffer)
// .resize(500) // 缩小宽度到 500px(高度按比例自适应)
.png({
palette: true, // 启用调色板
colours: 16, // 限制最大颜色数(1-256,根据图片复杂度调整)
compressionLevel: 9,
}) // 压缩为 PNG
// .toFile('output_from_buffer.png'); // 输出到文件
.toBuffer(); // 输出为 Buffer(而非文件)
///////////////////////////////////////////
编码为 PNG base64
const base64 = `data:image/png;base64,${compressedBuffer.toString('base64')}`;




![[C++探索之旅] 第一部分第十一课:小练习,猜单词 - 鹿快](https://img.lukuai.com/blogimg/20251015/da217e2245754101b3d2ef80869e9de2.jpg)










- 最新
- 最热
只看作者