当前位置:首页 » 《资源分享》 » 正文

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

16 人参与  2024年09月22日 13:21  分类 : 《资源分享》  评论

点击全文阅读


 

  使用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 接收变量和获取domconst 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 = 0const maxFrame = 60; // 假设最大值为100window.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>

 


点击全文阅读


本文链接:http://zhangshiyu.com/post/163094.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1