利用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. 如果为真,则返回以帧为单位的持续时间,如果为假,则以秒为单位。
- [propname: string]: 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([31, 64], true) // 播放指定的片段,([开始帧,结束帧], 是否立即播放)
- } else {
- a1.value.playSegments([0, 30], 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企服之家,中国第一个企服评测及商务社交产业平台。 |