vue element el-progress组件增强,鼠标移动到组件上时会触发一个回弹动画效果

有时候需求就是这么奇怪,要求鼠标移动到组件上面有一个动画回弹效果

组件代码如下(ts写法)

  1 <template>
  2     <div @mouseover="onMouseover" @mouseout="onMouseout">
  3         <el-progress
  4             v-bind="$attrs"
  5             :percentage="showPercentage"
  6             v-on="$listeners"
  7         ></el-progress>
  8     </div>
  9 </template>
 10 <script lang="ts">
 11 import { Component, Vue, Watch, Prop } from "vue-property-decorator";
 12 /**
 13  *
 14  * el-progress组件增强
 15  * 当鼠标移动到组件上时会触发一个动画效果
 16  *
 17  * 用法和el-progress一样
 18  *
 19  */
 20 @Component({
 21     name: "ZbProgress"
 22 })
 23 export default class ZbProgress extends Vue {
 24     // 百分比
 25     @Prop() percentage!: any;
 26     // 监听百分比数值
 27     @Watch("percentage", { immediate: true })
 28     updatePercentage(v: number) {
 29         // 因为需要通过改变百分比来实现动画效果
 30         // 所以这里将具体值赋值给一个内部字段
 31         this.showPercentage = v;
 32     }
 33     // 动画执行时间(毫秒)
 34     @Prop({ default: 200 }) animationTime!: number;
 35     // 动画波动百分比变化范围
 36     // 可以为负值
 37     @Prop({ default: 30 }) animationRange!: number;
 38     // 百分比显示值
 39     showPercentage: number = 0;
 40 
 41     // 是否正在执行动画
 42     isAnimationIng: boolean = false;
 43     // 上传鼠标离开元素时间
 44     outTime: number = 0;
 45     // 当鼠标移动到元素内时
 46     onMouseover() {
 47         // console.log("onMouseover鼠标移动到");
 48         // 获取鼠标上次离开时间
 49         const outTime = this.outTime;
 50         // 是否执行动画
 51         let is = true;
 52         if (outTime) {
 53             // 如果上次离开时间与当前时间间隔太短
 54             // 说明鼠标并没有真正的离开当前元素,只是在内部移动
 55             // 此时不执行动画
 56             is = new Date().getTime() - outTime > 100;
 57         }
 58         if (is) {
 59             // 执行动画
 60             this.showAnimation(this.showPercentage);
 61         }
 62     }
 63     // 当鼠标离开时
 64     onMouseout() {
 65         // console.log("onMouseout鼠标离开");
 66         // 记录当前离开时间
 67         this.outTime = new Date().getTime();
 68     }
 69     // 执行动画
 70     showAnimation(v: number) {
 71         const me = this as any;
 72         // 如果没用正在执行动画
 73         if (!me.isAnimationIng) {
 74             // 标识动画效果正则执行
 75             me.isAnimationIng = true;
 76             const {
 77                 // 动画波动百分比变化范围
 78                 animationRange,
 79                 // 动画执行时间(毫秒)
 80                 animationTime
 81             } = me;
 82             // 获取下个动画波动值
 83             let percentage = v - animationRange;
 84             // 将波动值限制到0-100
 85             if (percentage <= 0) {
 86                 percentage = 0;
 87             } else if (percentage >= 100) {
 88                 percentage = 100;
 89             }
 90             // 设置动画波动值
 91             me.showPercentage = percentage;
 92             setTimeout(() => {
 93                 // 延迟执行重置百分比,这样就能实现一个波动动效
 94                 me.showPercentage = v;
 95                 setTimeout(() => {
 96                     // 延迟标识动画效果已经结束
 97                     me.isAnimationIng = false;
 98                 }, 200);
 99             }, animationTime);
100         }
101     }
102 }
103 </script>

 使用

<template>
    <div>
        <zb-progress :show-text="false" :stroke-width="26" :percentage="70" :animationRange="-30">
        </zb-progress>
        <br />
        <zb-progress :show-text="false" :stroke-width="26" :percentage="30">
        </zb-progress>
        <br />
        <zb-progress :show-text="false" :stroke-width="26" :percentage="15" :animationTime='1000'>
        </zb-progress>
    </div>
</template>
<script lang="ts">
import { Component, Vue } from "vue-property-decorator";
@Component({ name: "elementProgress" })
export default class elementProgress extends Vue {}
</script>
原文地址:https://www.cnblogs.com/mlzs/p/14307628.html