css 实现百分比水波纹动画

194 阅读2分钟
场景:用水球展示数据百分占比,并添加动态水波纹效果。

image.png

实现

原理:将父元素设置为圆形,隐藏多余部分;根据波纹数添加子元素,并设置为圆形添然后加背景色;把子元素定位在父元素下方,并添加旋转动画,呈现效果就是水球波纹。

<div class="wave-wrap">
  <!-- 以左侧为例 -->
  <div class="wave left">
    <div class="percentage">{{ (rateData[0].value || 0) + '%' }}</div>
    <div class="wave1" :style="{ '--leftTop': leftTop }"></div>
    <div class="wave2" :style="{ '--leftTop': leftTop }"></div>
    <div class="wave3" :style="{ '--leftTop': leftTop }"></div>
  </div>
</div>
data() {
    return {
      leftTop: '100%',
      rateData: [{ name: '左侧', value: '72' }]
    };
},
created() {
    this.initCoverData();
},
methods: {
    initCoverData() {
      const calculateTop = index => {
        if (this.rateData[index].value) {
          const num = Number(this.rateData[index].value);
          return 100 - num + '%';
        } else {
          return '120%';
        }
      };
      this.leftTop = calculateTop(0);
    }
}
.wave-wrap {
  width: 400px;
  height: 200px;
  display: flex;
  align-items: center;
  justify-content: space-around;
  background: #0e2a52;
}
.wave {
  position: relative;
  border: 2px solid #3a5683;
  width: 106px;
  height: 106px;
  border-radius: 50%;
  text-align: center;
  overflow: hidden;
  background-color: rgba(205, 211, 255, 0.12);
  animation: water-wave linear infinite;
}
.percentage {
  position: relative;
  padding: 41px 0;
  color: #fff;
  text-align: center;
  font-family: DIN;
  font-size: 24px;
  font-weight: 500;
  line-height: 24px;
  z-index: 99;
}
.wave1 {
  position: absolute;
  left: -25%;
  opacity: 0.7;
  width: 200%;
  height: 200%;
  border-radius: 40%;
  animation: inherit;
  animation-duration: 5s;
}
.wave2 {
  position: absolute;
  left: -35%;
  opacity: 0.7;
  width: 200%;
  height: 200%;
  border-radius: 35%;
  animation: inherit;
  animation-duration: 7s;
}
.wave3 {
  position: absolute;
  left: -45%;
  opacity: 0.3;
  width: 200%;
  height: 200%;
  border-radius: 40%;
  animation: inherit;
  animation-duration: 11s;
}
@keyframes water-wave {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}
.left {
  .wave1 {
    top: var(--leftTop);
    border: 1px solid #33ffff;
    background: rgba(51, 255, 255, 0.5);
  }
  .wave2 {
    top: var(--leftTop);
    border: 1px solid #33ffff;
    background: rgba(51, 255, 255, 0.3);
  }
  .wave3 {
    top: var(--leftTop);
    border: 1px solid #33ffff;
    background: rgba(51, 255, 255, 0.2);
  }
}
// 右侧色值
.right {
  .wave1 {
    top: var(--rightTop); // 同左侧定义使用
    border: 1px solid #00a3ff;
    background: rgba(0, 163, 255, 0.5);
  }
  .wave2 {
    top: var(--rightTop);
    border: 1px solid #00a3ff;
    background: rgba(0, 163, 255, 0.3);
  }
  .wave3 {
    top: var(--rightTop);
    border: 1px solid #00a3ff;
    background: rgba(0, 163, 255, 0.2);
  }
}
备注

学习地址:www.jianshu.com/p/6edd98695…