84 lines
1.7 KiB
Vue
84 lines
1.7 KiB
Vue
<template>
|
|
<div ref="container" :style="{ width: props.width, height: props.height }" class="lottie-container"></div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, onMounted, onUnmounted, watch } from 'vue';
|
|
import lottie from 'lottie-web';
|
|
|
|
const props = defineProps({
|
|
path: { type: String, required: true },
|
|
loop: { type: Boolean, default: true },
|
|
autoplay: { type: Boolean, default: true },
|
|
width: { type: String, default: '100%' },
|
|
height: { type: String, default: '100%' },
|
|
play: { type: Boolean, default: true },
|
|
speed: { type: Number, default: 1 }
|
|
});
|
|
|
|
const container = ref(null);
|
|
let animation = null;
|
|
|
|
const initAnimation = () => {
|
|
if (animation) {
|
|
animation.destroy();
|
|
}
|
|
|
|
if (!container.value) return;
|
|
|
|
animation = lottie.loadAnimation({
|
|
container: container.value,
|
|
renderer: 'svg',
|
|
loop: props.loop,
|
|
autoplay: props.autoplay,
|
|
path: props.path
|
|
});
|
|
|
|
if (props.speed !== 1) {
|
|
animation.setSpeed(props.speed);
|
|
}
|
|
};
|
|
|
|
onMounted(() => {
|
|
initAnimation();
|
|
});
|
|
|
|
onUnmounted(() => {
|
|
if (animation) {
|
|
animation.destroy();
|
|
}
|
|
});
|
|
|
|
watch(() => props.path, () => {
|
|
initAnimation();
|
|
});
|
|
|
|
watch(() => props.play, (newVal) => {
|
|
if (animation) {
|
|
if (newVal) {
|
|
animation.play();
|
|
} else {
|
|
animation.stop();
|
|
}
|
|
}
|
|
});
|
|
|
|
defineExpose({
|
|
play: () => animation?.play(),
|
|
stop: () => animation?.stop(),
|
|
pause: () => animation?.pause(),
|
|
setSpeed: (speed) => animation?.setSpeed(speed),
|
|
goToAndPlay: (value, isFrame) => animation?.goToAndPlay(value, isFrame)
|
|
});
|
|
</script>
|
|
|
|
<style scoped>
|
|
.lottie-container {
|
|
overflow: hidden;
|
|
margin: 0 auto;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
</style>
|