场景:用水球展示数据百分占比,并添加动态水波纹效果。
实现
原理:将父元素设置为圆形,隐藏多余部分;根据波纹数添加子元素,并设置为圆形添然后加背景色;把子元素定位在父元素下方,并添加旋转动画,呈现效果就是水球波纹。
<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);
}
}