如何将Lottie动画渲染至Canvas?vue-lottie渲染异常求助
解决Lottie动画渲染到Canvas的问题
嘿,我看你在用vue-lottie时卡到了Canvas渲染的问题——明明设置了renderer为canvas,结果一直输出SVG对吧?别着急,咱们一步步排查问题,甚至可以直接用更底层的官方库来搞定,保证能让动画渲染到Canvas上。
问题排查
先看看你代码里的几个小坑:
- 组件属性拼写错了:
:heigh="1920"应该是:height="1920",这个小错误可能导致组件渲染异常 - vue-lottie的
container配置不用手动传字符串,组件会自己生成容器,你手动指定的"container"根本没被正确识别 - 动画数据修改的方式有点问题,得确保你修改的是正确的
animationData引用
方案1:修复vue-lottie的用法
调整代码,修正拼写并正确配置渲染器:
<template> <div> <!-- 修正height拼写,移除多余的container配置 --> <lottie :options="defaultOptions" :height="1920" :width="1080" v-on:animCreated="handleAnimation" /> </div> </template> <script> import * as animationData from "../data.json"; import Lottie from 'vue-lottie'; // 先复制一份动画数据,避免直接修改原文件引用 const animData = { ...animationData.default }; // 修改文本内容 animData.layers[0].t.d.k[0].s.t = "I hate sand"; animData.layers[1].t.d.k[0].s.t = "dope"; animData.layers[2].t.d.k[0].s.t = "nope"; animData.layers[3].t.d.k[0].s.t = "haha"; animData.layers[4].t.d.k[0].s.t = "n"; export default { components: { Lottie }, data() { return { defaultOptions: { animationData: animData, renderer: "canvas", // 明确指定Canvas渲染器 rendererSettings: { preserveAspectRatio: 'xMidYMid meet' // 可选,保持动画比例 } }, animationSpeed: 1, anim: null }; }, methods: { handleAnimation(anim) { this.anim = anim; // 这里打印确认渲染模式,应该输出canvas console.log('当前渲染器类型:', anim.renderer.type); }, stop() { this.anim?.stop(); }, play() { this.anim?.play(); }, pause() { this.anim?.pause(); }, onSpeedChange() { this.anim?.setSpeed(this.animationSpeed); } } }; </script> <style scoped> /* 给动画容器加个黑色背景,方便看效果 */ .lottie-container { background-color: black; } </style>
方案2:直接用lottie-web(更灵活)
如果vue-lottie的封装还是有玄学问题,直接用官方的lottie-web库,手动控制渲染到Canvas,自由度更高:
首先安装依赖:
npm install lottie-web
然后修改组件代码:
<template> <div> <!-- 手动创建动画容器,用ref获取DOM元素 --> <div id="lottie-container" ref="lottieContainer" style="width: 1080px; height: 1920px; background: black;" ></div> </div> </template> <script> import lottie from 'lottie-web'; import * as animationData from "../data.json"; export default { data() { return { anim: null, animationSpeed: 1 }; }, mounted() { // 复制并修改动画数据 const animData = { ...animationData.default }; animData.layers[0].t.d.k[0].s.t = "I hate sand"; animData.layers[1].t.d.k[0].s.t = "dope"; animData.layers[2].t.d.k[0].s.t = "nope"; animData.layers[3].t.d.k[0].s.t = "haha"; animData.layers[4].t.d.k[0].s.t = "n"; // 初始化动画,强制指定canvas渲染器 this.anim = lottie.loadAnimation({ container: this.$refs.lottieContainer, renderer: 'canvas', loop: true, autoplay: true, animationData: animData }); // 确认渲染模式 console.log('当前渲染器:', this.anim.renderer.type); }, beforeUnmount() { // 页面销毁时销毁动画,避免内存泄漏 this.anim?.destroy(); }, methods: { stop() { this.anim?.stop(); }, play() { this.anim?.play(); }, pause() { this.anim?.pause(); }, onSpeedChange() { this.anim?.setSpeed(this.animationSpeed); } } }; </script>
验证小技巧
不管用哪个方案,都可以通过打印anim.renderer.type来确认渲染模式,如果输出canvas就说明配置成功了。要是还是SVG,那可能是你AE导出的动画里有只能用SVG渲染的特殊元素(比如某些复杂滤镜),但大部分常规动画都支持Canvas渲染。
内容的提问来源于stack exchange,提问作者Coder Noob




