vue 占比动画进度条实例效果

vue yekong

vue 占比动画进度条实例效果
vue 数据可视化大屏中,有时会需要显示一个占比进度条,两种类型根据数量显示占比,但是直接把样式写出来,又感觉单调了一点,于是想着能不能增加一个动画效果呢?让这个占比有一个推进的效果。
vue 占比动画进度条实例效果动画
因为在之前已经写过一个类似的进度条占比效果,所以我们直接拿过来在之前的基础上微调一下就可以使用了。

首先把样式写出来,我们先给一个最小宽度,避免因为数值小导致内容无法完整显示,然后我们使用gsap来增加一个动画效果。让div从最小宽度达到原本应该占有的宽度,这样一个动画效果就出现了。

<template>
  <div class="progressBar">
    <div class="progressBars">
      <div class="progressBarsLine" :class="{progressBarsLine2:index==0}"
           :style="{background:'linear-gradient(270deg, '+item.bg1+' 0%, '+item.bg2+' 100%)'}"
           v-for="(item,index) in list2"
           :key="index">
        <span :class="'label'+index">{{ item.label }}({{ item.percentage }}%)</span>
        <span :class="'percentage'+index">{{ item.value }}人</span>
        <div v-if="index==0" class="lines"></div>
      </div>
    </div>
  </div>
</template>

<script>
import gsap from "gsap";

export default {
  name: "progressBar",
  components: {},
  props: {
    id: {
      type: String,
      default() {
        return '';
      }
    }
  },
  data() {
    return {
      list: [
        {
          label: '在职',
          value: 75,
          bg1: 'rgba(4, 189, 247, 1)',
          bg2: 'rgba(18, 99, 255, 1)',
        },
        {
          label: '退休',
          value: 25,
          bg1: 'rgba(51, 231, 191, 0)',
          bg2: 'rgba(105, 254, 221, 0)'
        },
      ],
    }
  },
  watch: {},
  computed: {
    list2: function () {
      let total = 0
      var list2 = this.list;
      var list = []
      this.list.forEach((type) => {
        total = total + type.value
      });
      list2.forEach((type) => {
        var data = {
          value: type.value,
          percentage: Number((type.value / total) * 100).toFixed(0),
          label: type.label,
          bg1: type.bg1,
          bg2: type.bg2,
        }
        list.push(data)
      });
      return list
    }
  },
  mounted() {
    var that = this;
    setTimeout(() => {
      gsap.to('.progressBarsLine2', {
        duration: 1.5, width: that.list2[0].percentage + '%', onComplete: () => {
          console.log('动画完成')
        }
      })
    }, 2500)
  },
  methods: {}
}
</script>

<style lang="scss" scoped>
.progressBars {
  width: calc(100% - 0px);
  margin: auto;
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: nowrap;
  flex-direction: row;
  background: linear-gradient(360deg, #33E7BF 0%, #69FEDD 100%);
  position: relative;
}

.progressBar {
  width: calc(100% - 0px);
  margin: 0 auto;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-wrap: nowrap;
  flex-direction: row;

  .progressBarsLine {
    color: #fff;
    font-size: 14px;
    display: flex;
    justify-content: center;
    align-items: center;
    flex-wrap: nowrap;
    flex-direction: row;
    height: 24px;
    position: relative;
    min-width: 20%;
  }

  .label0 {
    position: absolute;
    font-size: 14px;
    left: 0;
    top: 27px;
    font-family: PingFang SC-Bold, PingFang SC;
    font-weight: bold;
    color: rgba(215, 231, 255, 1);
  }

  .label1 {
    font-size: 14px;
    top: 27px;
    font-family: PingFang SC-Bold, PingFang SC;
    font-weight: bold;
    color: rgba(215, 231, 255, 1);
    right: 0;
    position: absolute;
  }


  .percentage0 {
    left: 12px;
    font-size: 14px;
    font-family: PingFang SC-Bold, PingFang SC;
    font-weight: bold;
    color: #FFFFFF;
    position: absolute;
  }

  .percentage1 {
    right: 12px;
    font-size: 14px;
    font-family: PingFang SC-Bold, PingFang SC;
    font-weight: bold;
    color: rgba(2, 29, 107, 1);
    position: absolute;
  }

  p:first-child {
    border-radius: 5px 0 0 5px;
  }

  p:last-child {
    border-radius: 0 5px 5px 0;
  }
}

.lines {
  width: 2px;
  height: 28px;
  background: #FFFFFF;
  opacity: 1;
  position: absolute;
  right: 0;
}
</style>

喜欢