簡述
日常工作中,有可能遇到圓環進度條的需求,此處給出圓環進度條的DEMO。
DEMO
點此查看效果。
代碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>draw-progress</title>
</head>
<body>
<canvas id="canvas" width="180" height="180"></canvas>
<script>
const canvas = document.querySelector('#canvas')
drawProgress(canvas, 60, '#2196f3', '#eef7e4', 'This is tips info')
function drawProgress (canvasEle, percent, foregroundColor, backgroundColor, tips) {
const context = canvasEle.getContext('2d')
const circleLineWidth = 8 * getPixelRatio(context)
// 高清屏繪製時是多倍像素,保持邏輯像素不變,增加物理像素,保證其在高清屏清晰顯示
canvasEle.style.width = canvasEle.width + 'px'
canvasEle.style.height = canvasEle.height + 'px'
canvasEle.width = canvasEle.width * getPixelRatio(context)
canvasEle.height = canvasEle.height * getPixelRatio(context)
const centerX = canvasEle.width / 2
const centerY = canvasEle.height / 2
const rad = Math.PI * 2 / 100
let curProgress = 0
function getPixelRatio (context) {
const backingStore = context.backingStorePixelRatio ||
context.webkitBackingStorePixelRatio ||
context.mozBackingStorePixelRatio ||
context.msBackingStorePixelRatio ||
context.oBackingStorePixelRatio ||
context.backingStorePixelRatio || 1
return (window.devicePixelRatio || 1) / backingStore
}
function backgroundCircle () {
context.save()
context.beginPath()
context.lineWidth = circleLineWidth
// 線條只有 1/2 在圓內,因此除以2
const radius = centerX - circleLineWidth / 2
context.lineCap = 'round'
context.strokeStyle = backgroundColor
context.arc(centerX, centerY, radius, 0, Math.PI * 2, false)
context.stroke()
context.closePath()
context.restore()
}
function foregroundCircle (progress) {
context.save()
context.strokeStyle = foregroundColor
context.lineWidth = circleLineWidth
context.lineCap = 'round'
const radius = centerX - circleLineWidth / 2
context.beginPath()
context.arc(centerX, centerY, radius, -Math.PI / 2, -Math.PI / 2 + progress * rad, false)
context.stroke()
context.closePath()
context.restore()
}
function drawText () {
context.save()
context.fillStyle = '#000'
const fontSize = 18 * getPixelRatio(context)
context.font = fontSize + 'px sans-serif'
context.textBaseline = 'bottom'
const textWidth = context.measureText(tips).width
context.fillText(tips, centerX - textWidth / 2, centerY + fontSize / 2)
context.restore()
}
(function drawFrame () {
window.requestAnimationFrame(drawFrame)
context.clearRect(0, 0, canvasEle.width, canvasEle.height)
backgroundCircle()
foregroundCircle(curProgress)
drawText()
if (curProgress >= percent) return
curProgress += 10
}())
}
</script>
</body>
</html>