先上图,看下效果【这是本人纯css 渲染】
重要点记录:
1.从粗到细的进度条(设定父div 的相对定位,利用三角形的思想,渲染此进度条)
.progress {
position: absolute;
top: -0.01rem;
left: -0.04rem;
width: 0;
height: 0;
border: 3px solid transparent;
border-right: var(--borderWidth) solid var(--borderColor);
transform: rotate(0.6deg);//加旋转角度是因为 默认不是与父div对齐的,可根据自己的进行调整
}
2.smtline 的css
.smt-line {
display: inline-block;
width: 100%;
height: 0.35rem;
border-bottom: 2px solid #282e33;
position: relative;
margin-bottom: 0.15rem;
color: #fff;
line-height: 0.25rem;
font-size: 0.2rem;
font-weight: bold;
&:after {
content: "";
display: inline-block;
position: absolute;
top: 0.1rem;
right: 0;
width: 0;
height: 0;
border: 0.07rem solid transparent;
border-right: 0.1rem solid #0777c6;
line-height: 14px;
}
&:before {
content: "";
display: inline-block;
position: absolute;
width: 0.15rem;
top: 0.325rem;
right: 0;
height: 0;
border: 1px solid #fff;
}
}
}
完整代码如下:
<template>
<div class="progress-be-yield">
<div class="smt-line">BE Yield</div>
<div class="beyield-box">
<div class="beyield" v-for="item in data">
<div class="name">{{ item.name }}</div>
<div class="content">
<div ref="value" class="value" :style="{ '--bgColor': item.value > 0.5 ? '#0e275f' : item.value > 0.25 ? '#4d382b' : '#4a1d28' }"></div>
<div class="text">{{ item.value * 100 }}%</div>
<div
class="progress"
v-if="divWidth"
:style="{
'--borderWidth': item.value > 0.5 ? `${divWidth * item.value}px ` : item.value > 0.25 ? `${divWidth * item.value}px` : `${divWidth * item.value}px`,
'--borderColor': item.value > 0.5 ? `#4891ff` : item.value > 0.25 ? `#f0aa48` : `#f04545`,
}"
></div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "ProgressBeYield",
props: { data: Array },
watch: {
data: {
handler(newVal) {
this.$nextTick(() => {
this.divWidth = this.$refs.value[0].offsetWidth;
console.log(this.divWidth);
});
},
deep: true,
immediate: true,
},
},
computed: {},
data() {
return {
divWidth: 0,
};
},
methods: {},
mounted() {},
};
</script>
<style scoped lang="scss">
.progress-be-yield {
width: 100%;
height: 100%;
.beyield-box {
padding: 0.1rem;
.beyield {
padding-top: 0.1rem;
.name {
color: #fff;
font-size: 0.16rem;
margin-bottom: 0.1rem;
}
.content {
display: flex;
justify-content: space-between;
align-content: center;
position: relative;
.progress {
position: absolute;
top: -0.01rem;
left: -0.04rem;
width: 0;
height: 0;
border: 3px solid transparent;
border-right: var(--borderWidth) solid var(--borderColor);
transform: rotate(0.6deg);
&:before {
content: "";
display: inline-block;
position: absolute;
top: -0.04rem;
left: calc(var(--borderWidth) - 0.04rem);
width: 0.08rem;
height: 0.08rem;
background: var(--borderColor);
border-radius: 50%;
outline: 3px solid rgba(166, 255, 206, 0.15);
outline-offset: 9px;
animation: outlineOpacity 4s ease-in-out infinite;
}
&:after {
content: "";
display: inline-block;
position: absolute;
top: -0.1rem;
left: calc(var(--borderWidth) - 0.1rem);
width: 0.2rem;
height: 0.2rem;
background: rgba(166, 255, 206, 0.15);
border-radius: 50%;
animation: widthHightOpacity 4s ease-in-out infinite;
// animation-delay: 1s;
}
}
.value {
background-color: var(--bgColor);
width: 100%;
}
.text {
color: #ebedf0;
margin-left: 0.2rem;
font-size: 0.16rem;
font-weight: bold;
}
}
}
}
}
@keyframes outlineOpacity {
0% {
opacity: 1;
outline-offset: 9px;
}
50% {
opacity: 0.4;
outline-offset: 16px;
}
100% {
opacity: 1;
outline-offset: 9px;
}
}
@keyframes widthHightOpacity {
0% {
opacity: 1;
width: 0.2rem;
height: 0.2rem;
}
50% {
left: calc(var(--borderWidth) - 0.15rem);
top: -0.15rem;
opacity: 0.4;
width: 0.3rem;
height: 0.3rem;
}
100% {
opacity: 1;
width: 0.2rem;
height: 0.2rem;
}
}
</style>