项目需求:要做饼图倒计时效果。
一开始只想到了用 border-radius 来实现,但只能拆分成 4 个半圆。动态显示没有倒计时的类似效果。
通过查看资料发现 Css3 中的 skewY 属性可以实现类似的需求,旋转角度可以从 0° 到 90°,这样再配合 border-radius 就可以实现想要的效果了。
具体使用方法如下:
<template>
<div class="pie">
<div class="pie-box pie-right-top" :class="{ 'bg-1F7070': circle.rightTop }"></div>
<div class="pie-box pie-left-top" :class="{ 'bg-1F7070': circle.leftTop }"></div>
<div class="pie-box pie-right-bottom" :class="{ 'bg-1F7070': circle.rightBottom }"></div>
<div class="pie-box pie-left-bottom" :class="{ 'bg-1F7070': circle.leftBottom }"></div>
<div class="slice" :style="`transform: rotate(${circle.angleR}deg) skewY(${circle.angleS}deg);`">
<div class="slice-contents" :style="`transform: skewY(${circle.angleC}deg);`"></div>
</div>
<template>
export default {
data() {
return {
examTime: '',
circle: {
// 考试进度相关参数
leftTop: false,
leftBottom: false,
rightTop: false,
rightTop: false,
angleS: -90,
angleC: 90,
angleR: 0
},
timer: {} // 定时器
};
},
async mounted() {
this.examTime = sessionStorage.timeDiff;
// 是否执行倒计时
if (sessionStorage.timeDiff) {
this.timer = setInterval(() => {
this.counDown();
}, 1000);
}
},
destroyed() {
// 清除定时器
clearInterval(this.timer);
},
methods: {
// 处理倒计时
counDown() {
let [hour, minute, second] = this.examTime.split(":");
if (second - 1 >= 0) {
second--;
} else {
if (minute - 1 >= 0) {
minute--;
second = 59;
} else {
if (hour - 1 >= 0) {
hour--;
minute = second = 59;
}
}
}
// Css3处理进度旋转
this.circle.angleS++;
this.circle.angleC--;
if (this.circle.angleS === 0) {
this.circle.angleR += 90;
this.circle.angleS = -90;
this.circle.angleC = 90;
}
switch (this.circle.angleR) {
case 90:
this.circle.leftTop = true;
break;
case 180:
this.circle.leftBottom = true;
break;
case 270:
this.circle.rightBottom = true;
break;
case 360:
this.circle.rightTop = true;
clearInterval(this.timer);
break;
}
this.examTime = `${hour.toString().padStart(2, "0")}:${minute
.toString()
.padStart(2, "0")}:${second.toString().padStart(2, "0")}`;
},
</script>
<style lang="less" scoped>
.pie-box {
height: 50%;
width: 50%;
}
.pie-right-top {
border-radius: 100% 0 0;
}
.pie-left-top {
border-radius: 0 100% 0 0;
}
.pie-right-bottom {
border-radius: 0 0 0 100%;
}
.pie-left-bottom {
border-radius: 0 0 100%;
}
.pie {
margin: 15px auto;
display: flex;
flex-wrap: wrap;
width: 100px;
height: 100px;
border-radius: 50%;
background-color: #d8d8d8;
position: relative;
}
.slice {
overflow: hidden;
position: absolute;
top: 0;
right: 0;
width: 50%;
height: 50%;
transform-origin: 0% 100%;
}
.slice-contents {
position: absolute;
left: -100%;
width: 200%;
height: 200%;
border-radius: 50%;
background-color: #1f7070;
}
</style>