官方介绍:Lottie是一个库,可以解析使用AE制作的动画(需要用bodymovie导出为json格式),支持web、ios、android、flutter和react native。 在web端,lottie-web库可以解析导出的动画json文件,并将其以svg或者canvas的方式将动画绘制在我们的页面上.
npm install lottie-web
复制代码
import lottie from 'lottie-web'
const animation = lottie.loadAnimation({
container: document.getElementById('domId'), // 绑定dom节点
renderer: 'svg', // 渲染方式:svg、canvas
loop: true, // 是否循环播放,默认:false
autoplay: true, // 是否自动播放, 默认true
animationData: // AE动画使用bodymovie导出为json数据
})
{
"v": "5.1.13", // bodymovin 版本
"fr": 30, // 帧率
"ip": 0, // 起始关键帧
"op": 20, // 结束关键帧
"w": 150, // 视图宽
"h": 130, // 视图高
"nm": "鹅头收起动画", // 名称
"ddd": 0, // 3d
"assets": [], // 资源集合
"layers": [], // 图层集合
"masker": [] // 蒙层集合
}
animation.play(); // 播放,从当前帧开始播放
animation.stop(); // 停止,并回到第0帧
animation.pause(); // 暂停,并保持当前帧
animation.goToAndStop(value, isFrame); // 跳到某个时刻/帧并停止isFrame(默认false)指示value表示帧还是时间(毫秒)
animation.goToAndPlay(value, isFrame); // 跳到某个时刻/帧并进行播放
animation.goToAndStop(30, true); // 跳转到第30帧并停止
animation.goToAndPlay(300); // 跳转到第300毫秒并播放
animation.playSegments(arr, forceFlag); // arr可以包含两个数字或者两个数字组成的数组,forceFlag表示是否立即强制播放该片段
animation.playSegments([10,20], false); // 播放完之前的片段,播放10-20帧
animation.playSegments([[0,5],[10,18]], true); // 直接播放0-5帧和10-18帧
animation.setSpeed(speed); // 设置播放速度,speed为1表示正常速度
animation.setDirection(direction); // 设置播放方向,1表示正向播放,-1表示反向播放
animation.destroy(); // 删除该动画,移除相应的元素标签等。
animation.addEventListener('data_ready', () => {}) // 动画数据加载完毕
animation.addEventListener('config_ready', () => {}) // 完成初始配置后
animation.addEventListener('data_failed', () => {}) // 加载动画数据失败
animation.addEventListener('loaded_images', () => {}) // 所有图片加载成功或者失败
animation.addEventListener('DOMLoaded', () => {}) // 将元素添加到DOM后
* complete: 播放完成(循环播放下不会触发)
* loopComplete: 当前循环下播放(循环播放/非循环播放)结束时触发
* enterFrame: 每进入一帧就会触发,播放时每一帧都会触发一次,stop方法也会触发
* segmentStart: 播放指定片段时触发,playSegments、resetSegments等方法刚开始播放指定片段时会发出,如果playSegments播放多个片段,多个片段最开始都会触发。
* data_ready: 动画json文件加载完毕触发
* DOMLoaded: 动画相关的dom已经被添加到html后触发
* destroy: 将在动画删除时触发
之前我们说过Lottie
的动画是通过AE制作好了动画后,再使用bodymovie导出为json格式。其实有一个网站,它提供了一些免费的动画(当然也有付费的)直接有我们需要的动画json数据.
如下面的动图, 我们找到我们想要的动画,然后点击后,弹出窗口,点击下载,格式为JSON。然后就能把这个动画的json数据用到我们自己的项目里边去了.
好了介绍完了它的用法后,我们现在就去vue
中去做一个实战
npm init @vitejs/app
复制代码
npm install lottie-web
复制代码
lottie.vue
, 主要就是初始化好lottie对象,然后把对象传递出去给其他组件用
<div :style="style" ref="lavContainer">div>
<script>
import lottie from ‘lottie-web’
export default {
name: ‘lottie’,
props: {
options: {
type: Object,
required: true,
},
height: Number,
width: Number,
},
computed: {
style() {
return {
width: this.width ? ${this.width}px
: ‘100%’,
height: this.height ? ${this.height}px
: ‘100%’,
}
},
},
mounted() {
this.anim = lottie.loadAnimation({
container: this.KaTeX parse error: Expected 'EOF', got '}' at position 798: …ta, }̲) emit(‘animCreated’, this.anim)
},
unmounted () {
this.anim && this.anim.destroy()
}
}
script>
复制代码
clickIcon
,这个组件也是通用组件,增加了点击后,动画交互需要怎么走向等逻辑.
<div class="clickIcon">
<div
class="iconBox"
:style="{ width: width + 'px', height: height + 'px' }"
>
<slot name="svg" v-bind:data="{ toggle, flag, iconWidth, iconHeight }">slot>
<lottie
@click="toggle"
:class="{ show: flag === true || !defaultSlot }"
class="like"
style="display: none;"
:options="options"
:height="height"
:width="width"
v-on:animCreated="handleAnimation"
/>
div>
div>
<script>
import { computed, ref, defineComponent } from “vue”;
import Lottie from “./lottie.vue”;
let anim = null
/**
export default defineComponent({
name: “clickIcon”,
props: {
// 宽度
width: {
type: Number,
default: 100,
},
// 高度
height: {
type: Number,
default: 100,
},
// 初始化Lottie需要的参数
options: {
type: Object,
default: () => {},
},
// 是否需要一个插槽,显示一个默认的图标
defaultSlot: {
type: Boolean,
default: true
},
// 从外面传递的一个点击后需要的交互效果
toggleFun: {
type: Function,
default: null
}
},
components: {
lottie: Lottie,
},
emits: [‘init’],
setup(props, { emit }) {
// 动画速度
const animationSpeed = 2
// 点击交互标识
let flag = ref(false);
// 图标高度
const iconWidth = computed(() => {
return props.width;
});
// 图标宽度
const iconHeight = computed(() => {
return props.height;
});
// 点击图标交互
const toggle = function() {
if (!props.defaultSlot) {
props.toggleFun && props.toggleFun(anim)
} else {
flag.value = !flag.value;
if (flag.value) {
anim.play();
} else {
anim.stop();
}
}
};
// 获取anim对象
const handleAnimation = function(animated) {
anim = animated;
onSpeedChange()
emit(‘init’, animated)
}
// 停止动画
const stop = function() {
anim.stop();
}
// 播放动画
const play = function() {
anim.play();
}
// 暂停动画
const pause = function() {
anim.pause();
}
// 控制播放速度
const onSpeedChange = function() {
anim.setSpeed(animationSpeed);
}
return {
iconWidth,
iconHeight,
handleAnimation,
flag,
toggle,
stop,
play,
pause
};
},
});
script>
<style scoped>
.iconBox {
position: relative;
}
.show {
display: inline-block ;
}
.hidden {
display: none ;
}
.like {
cursor: pointer;
}
.icon {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
style>
复制代码
接下来我们就写一个喜欢
组件like.vue
,如之前我们看到的效果 先把下载的动画json文件,放到资源文件目录,然后我们再用代码调用它使用.
<lottie
class="like"
:options="defaultOptions"
:height="height"
:defaultSlot="false"
:width="width"
@init="init"
:toggleFun="toggle"
ref="lottie"
>
lottie>
<script>
import Lottie from “…/common/clickIcon.vue”;
import animationData from “/public/like.json”;
export default {
name: “app”,
components: {
lottie: Lottie,
},
props: {
width: {
type: Number,
default: 60,
},
height: {
type: Number,
default: 60,
},
},
methods: {
init (animation) {
animation && animation.goToAndStop(0, true)
},
toggle (animation) {
if (this.toggleFlag) {
animation.playSegments([50, 90], true); // 从50帧播放到最后
} else {
animation && animation.playSegments([0, 50], true); // 从第0帧播放到50帧
}
this.toggleFlag = !this.toggleFlag
}
},
data() {
return {
toggleFlag: false,
defaultOptions: {
name: “like”,
animationData: animationData,
autoplay: false,
loop: false,
}
};
}
};
script>
<style scoped>
.hidden {
display: none;
}
style>
复制代码
上边的效果之所以这样做,是因为我们下载的‘喜欢’动画的json文件,它是由两个状态组成的, 0-50帧是由未选中到选中状态的动画,50->90帧是选中状态->未选中状态的动画. 具体多少帧到多少帧可以从网站下载json文件那个窗口下面的进度去看到的.
喜欢
组件
<div id="app">
<like>like>
div>