效果如下
分析:将进度条分为两个部分,背景环与实体环,实体环包括中间文字,因此使用两个画布来实现。
代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<style>
body {
padding: 0;
margin: 0;
}
.box {
position: relative;
width: 200;
height: 200;
}
.bc,
.pc {
position: absolute;
left: 0;
top: 0;
}
</style>
</head>
<body>
<div class="box"></div>
<script>
const bc = document.createElement('canvas')
const pc = document.createElement('canvas')
const box = document.querySelector('.box')
const WIDTH = 200
const HEIGHT = 200
const LINE_WIDTH = 10
bc.setAttribute('class', 'bg')
pc.setAttribute('class', 'pc')
bc.width = pc.width = WIDTH
bc.height = pc.height = HEIGHT
box.appendChild(bc)
box.appendChild(pc)
let bctx = bc.getContext('2d')
let pctx = pc.getContext('2d')
bctx.lineWidth = pctx.lineWidth = LINE_WIDTH
bctx.strokeStyle = '#ebebeb'
pctx.strokeStyle = 'red'
pctx.lineCap = 'round'
pctx.font = '50px Arial'
pctx.textAlign = 'center'
pctx.textBaseline = 'middle'
pctx.fillStyle = 'gray'
bctx.beginPath()
bctx.arc(
100,
100,
WIDTH / 2 - LINE_WIDTH / 2,
0,
Math.PI * 2,
false
)
bctx.stroke()
bctx.closePath()
let angle = 0
function draw() {
pctx.clearRect(0, 0, 200, 200)
pctx.beginPath()
pctx.arc(
100,
100,
WIDTH / 2 - LINE_WIDTH / 2,
0,
(Math.PI * angle * 2) / 100,
false
)
pctx.stroke()
pctx.closePath()
pctx.beginPath()
pctx.fillText(angle + '%', 100, 100)
if (angle < 80) {
window.requestAnimationFrame(draw)
}
angle++
}
window.requestAnimationFrame(draw)
</script>
</body>
</html>