天津储鑫盛钢材现货供应商 发表于 2024-9-17 03:29:49

vue3中lottie-web封装组件和api的利用

 https://i-blog.csdnimg.cn/blog_migrate/4bcf07dc4c0631c6abfca1098df53211.gif
https://i-blog.csdnimg.cn/blog_migrate/371dc8bf5c308914c65015ce69e41f4a.png
     利用ts的话定义范例components/Lottie/type.ts
type Segment = [ number, number]

export interface LottieEvent {
play: () => void, // 播放动画
pause: () => void, // 暂停动画
stop: () => void, // 停止动画
setSpeed: (speed: number) => void, // 设置播放速度,1 表示1倍速度,0.5 表示 0.5倍速度
goToAndStop: (value: number, isFrame?: boolean) => void, // 跳到某一帧或某一秒停止,第二个参数 isFrame 为是否基于帧模式还是时间,默认为 false
goToAndPlay: (value: number, isFrame?: boolean) => void, // 跳到某一帧或某一秒开始,第二个参数 isFrame 为是否基于帧模式还是时间,默认为 false
setDirection: (direction: 1 | -1) => void, // 设置播放方向,1 表示正向播放,-1 表示反向播放
playSegments: (segments: Segment[], forceFlag?: boolean) => void, // 播放指定的片段,参数1为数组,两个元素为开始帧和结束帧;参数2为,是否立即播放片段,还是等之前的动画播放完成
destroy: () => void, // 销毁动画
getDuration: (isFrames: boolean) => void,// 获取动画时长,参数为是否基于帧模式,默认为 false. 如果为真,则返回以帧为单位的持续时间,如果为假,则以秒为单位。


: any
}

// Events
// onComplete - 播放完成时触发
// onLoopComplete - 循环播放完成时触发
// onEnterFrame - 每一帧播放时触发
// onSegmentStart - 播放指定片段开始时触发    封装组件 components/Lottie/index.vue 
<script setup>
import { ref, onMounted } from 'vue'
import lottie from 'lottie-web'

// 设置组件参数
const props = defineProps({
renderer: {
    type: String,
    default: 'svg',
},
// 循环播放
loop: {
    type: Boolean,
    default: true,
},
autoplay: {
    type: Boolean,
    default: true,
},
animationData: {
    type: Object,
    default: () => ({}),
},
name: {
    type: String,
    default: '',
}
})

// 创建 lottie 接收变量和获取dom
const animation = ref(null)
const dom = ref(null)

// 创建事件返回初始化lottie对象
const emits = defineEmits(['getAnimation', 'getDom'])

// 初始化渲染 lottie动画,并返回lottie对象
onMounted(() => {
animation.value = lottie.loadAnimation({
    container: dom.value,// 用于渲染的容器
    // 渲染方式 svg、canvas、html
    renderer: props.renderer,
    // 是否循环
    loop: props.loop,
    autoplay: props.autoplay, // 自动播放
    // UED 提供的 动画的 json 文件
    animationData: props.animationData,
    name: props.name,
});
emits('getAnimation', animation.value)
})
</script>

<template>
    <!-- 渲染 lottie 动画 -->
    <div id="lottieId" ref="dom"></div>
</template>

<style scoped>

#lottieId {
width: 100%;
height: 100%;
}

</style>
   引用组件,例如HelloWord.vue
<script setup>
import { ref, onMounted, watch } from 'vue'
import Lottie from './Lottie/index.vue'
import Animation from '../assets/Animation - 1712559820721.json'
import Animation1 from '../assets/Animation-1.json'

const a1 = ref(null)
const count = ref(0)
const likeFlag = ref(false)

const getAnimation = (animation) => {
a1.value = animation
if (a1.value) {
    a1.value.addEventListener('enterFrame', () => {
      // console.log(a1.value, '--a1.value--');
      if (a1.value.currentFrame >= 63) { // 当前帧
      a1.value.goToAndPlay(0, true) // 跳转到指定帧开始
      }
    })
    a1.value.addEventListener('complete', () => {
      console.log('播放完毕');
    })
}
}
const play = () => {
if (likeFlag.value) {
    a1.value.playSegments(, true) // 播放指定的片段,([开始帧,结束帧], 是否立即播放)
} else {
    a1.value.playSegments(, true)
}
likeFlag.value = !likeFlag.value
count.value++
}

// const likeClick = () => {
//   console.log('likeClick');
//   a1.value.setSpeed(2) // 设置播放速度
//   // a1.value.setDirection(-1) // 设置播放速度,不知道什么原因这里没有生效
//   a1.value.stop()
//   setTimeout(() => {
//   // a1.value.goToAndStop(31, true) // 跳到指定帧结束,第二个参数 isFrame 为是否基于帧模式还是时间,默认为 false
//   // a1.value.goToAndPlay(21, true) // 跳转到指定帧开始
//   a1.value.play();
//   }, 100); // 延迟100毫秒播放
//   const duration = a1.value.getDuration(true) // true 为帧, false 为秒
//   console.log(duration, '--duration--'); // 64帧 2.56秒
// }

// 监听鼠标滚动事件
let frame = 0
const maxFrame = 60; // 假设最大值为100
window.addEventListener('wheel', (event) => {
console.log(event, '--event--');
if (event.wheelDelta < 0) {
    frame += 10
    count.value++
} else if (event.wheelDelta >= 149) {
    frame -= 10
    count.value--
}
if (frame >= maxFrame) {
    frame = 0; // 重置为0
} else if (frame < 0) {
    frame = maxFrame; // 重置为最大值
}
a1.value.goToAndStop(frame, true)
console.log(frame, '--frame--');

})

onMounted(() => {
})
</script>

<template>

<div class="card">
    <div>
      <Lottie :animation-data="Animation" />
    </div>
    <div class="card-body">
      <Lottie class="a1" :animation-data="Animation1" :loop="false" :autoplay="true" @get-animation="getAnimation"
      @click="likeClick" />
      <button @click="play">Play</button>
      <div class="count">{{ count }}</div>
      <div class="info">测试内容</div>
    </div>
</div>

</template>

<style scoped>
.card {
display: flex;
align-items: center;
width: 700px;

/* margin: 0 auto; */
.card-body {
    position: relative;

    .info {
      position: absolute;
      left: 50%;
      top: 20%;
      transform: translate(-50%, -50%);
      color: rgb(255, 255, 255);
    }
}
}
</style>
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: vue3中lottie-web封装组件和api的利用