<template>
<view class="progress_box" @click="secondDuce()">
<view id="circleBg" class="circleBg">
<div class="circleBg-center"></div>
</view>
<view id="circle" class="circle" :style="clipPathStyle ? clipPathStyle : ''">
<div class="circle-center"></div>
</view>
<div id="seconds" class="second">{{ seconds }}</div>
</view>
</template>
<script>
export default {
props: {
circlePgParams: {
type: Object,
default: function() {
return {
progressRate: 0.85,
radius: 100,
lineWidth: 12,
lineCap: 'round',
startColor: '#38A4F5',
endColor: '#38A4F5',
bgColor: '#EBEBEB',
title: 300,
subTitle: '副标题',
fontSize: 28,
rpx: 1
}
}
}
},
data() {
return {
circleStyle: 0,
circleRadius: 0,
centerPoision: 0,
clipPathStyle: '',
seconds: 0
}
},
mounted() {
this.seconds = (10 * Math.random()).toFixed(2)
this.step(this.seconds / 10, 100, 'circle')
// this.init()
},
methods: {
//点击触发事件
secondDuce() {
this.clipPathStyle = ''
this.seconds = (10 * Math.random()).toFixed(2)
//画圆环
this.step(this.seconds / 10, 100, 'circle')
},
/**
* @params percent 圆环百分比
* @params r 圆环外径,原div宽的三分之一
* @params domId dom元素类名
* @params pxiel 单位
**/
async step(percent, r, domId, pxiel = 'px') {
var _this = this
// 获取元素
let view = await uni.createSelectorQuery().in(this)
await view
.select('#' + domId)
.boundingClientRect(function(data) {
// data - 各种参数
console.log(data)
_this.circleStyleFunc(data.width, pxiel, 0)
let initPercent = 0
var timer = setInterval(() => {
if (initPercent < percent) {
initPercent += 0.02
initPercent = initPercent > 1 ? 1 : initPercent
if (initPercent > 0) {
_this.circleStyleFunc(data.width, pxiel, initPercent)
}
} else {
clearInterval(timer)
timer = null
initPercent = 0
}
}, 20)
})
.exec()
},
circleStyleFunc(L, pxiel, percent) {
if (percent <= 0) return
// 包含圆环的div长度高度为 L
var r = L
// 总共7个点
var p1 = [L / 2, L / 2],
p2 = p1,
p3 = p2,
p4 = p2,
p5 = p2,
p6 = p2
var angle = Math.PI * 2 * percent.toFixed(1)
percent = percent > 1 ? 1 : percent
console.log('percent, angle:', percent, angle)
if (angle <= Math.PI / 2) {
p1 = [L / 2, L / 2]
p2 = [L / 2, L]
p3 = [L / 2 - r * Math.sin(angle), L / 2 + r * Math.cos(angle)]
p4 = p3
p5 = p3
p6 = p3
} else if (angle >= Math.PI / 2 && angle <= Math.PI) {
p1 = [L / 2, L / 2]
p2 = [L / 2, L]
p3 = [0, L / 2]
p4 = [L / 2 - r * Math.cos(angle - Math.PI / 2), L / 2 - r * Math.sin(angle - Math.PI / 2)]
p5 = p4
p6 = p4
} else if (angle >= Math.PI && angle <= 1.5 * Math.PI) {
p1 = [L / 2, L / 2]
p2 = [L / 2, L]
p3 = [0, L / 2]
p4 = [L / 2, 0]
p5 = [L / 2 + r * Math.sin(angle - Math.PI), L / 2 - r * Math.cos(angle - Math.PI)]
p6 = p5
} else if (angle >= 1.5 * Math.PI && angle <= 2 * Math.PI) {
p1 = [L / 2, L / 2]
p2 = [L / 2, L]
p3 = [0, L / 2]
p4 = [L / 2, 0]
p5 = [L, L / 2]
p6 = [L / 2 + r * Math.cos(angle - (Math.PI * 3) / 2), L / 2 + r * Math.sin(angle - (Math.PI * 3) / 2)]
}
let pArr = [p1, p2, p3, p4, p5, p6]
this.clipPathStyle = ''
for (let i = 0; i < pArr.length; i++) {
if (pArr[i]) {
this.clipPathStyle = this.clipPathStyle + pArr[i][0] + pxiel + ' ' + pArr[i][1] + pxiel
this.clipPathStyle = this.clipPathStyle + ','
}
}
this.clipPathStyle = 'clip-path: polygon(' + this.clipPathStyle.substring(0, this.clipPathStyle.length - 1) + ');'
console.log('this.clipPathStyle', this.clipPathStyle)
},
init() {
if (this.circlePgParams) {
this.circleStyle = Math.ceil(
(this.circlePgParams.lineWidth / this.circlePgParams.rpx +
this.circlePgParams.radius / this.circlePgParams.rpx) *
2
)
this.circleRadius = Math.floor((this.circlePgParams?.radius / this.circlePgParams.rpx || 100) / 2) - 10
this.centerPoision = Math.floor(this.circleStyle / this.circlePgParams.rpx / 2)
this.drawProgressbg()
this.drawCircleAnimate()
}
}
}
}
</script>
<style>
.progress_box {
position: relative;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
}
.progress_bg {
position: absolute;
width: 30vw;
height: 30vw;
display: none;
}
.progress_bar {
width: 30vw;
height: 30vw;
display: none;
}
.circleBg {
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 300rpx;
height: 300rpx;
border-radius: 50%;
position: absolute;
transition: clip-path 0.2s;
//遮罩,要小于圆环的半径,否则会全遮住
-webkit-mask: radial-gradient(transparent 70rpx, #000 70rpx);
mask: radial-gradient(transparent 70rpx, #000 70rpx);
overflow: hidden;
}
.circleBg-center {
margin: 17%;
width: 66%;
height: 66%;
border-radius: 50%;
background: #ebebeb;
}
.circle {
width: 300rpx;
height: 300rpx;
border-radius: 50%;
position: relative;
transition: clip-path 0.2s;
-webkit-mask: radial-gradient(transparent 70rpx, #000 70rpx);
mask: radial-gradient(transparent 70rpx, #000 70rpx);
overflow: hidden;
}
.circle-center {
margin: 17%;
width: 66%;
height: 66%;
border-radius: 50%;
background: #38a4f5;
}
.second {
position: absolute;
left: 50%;
top: 50%;
width: 200rpx;
height: 200rpx;
line-height: 200rpx;
text-align: center;
font-size: 20rpx;
transform: translate(-50%, -50%);
}
</style>
uniapp解决canvas画圆环,层级过高挡住其他元素,解法1(polygon+遮罩)
最新推荐文章于 2024-06-06 20:56:55 发布