- 主要用到的函数也就是arc函数
- 实现的核心其实是增量,就是上次结束的弧度成为下次弧度的开始,便可以平滑过度。
- 关于动画,有个实现原理,就是一秒最少要20fps。(fps是帧)
效果图

一言不合贴的代码:
<!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>甜甜圈</title>
<style>
* {
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<canvas id="pan"></canvas>
</body>
<script>
// 初始化函数
var pan = document.getElementById('pan')
var width = window.outerWidth
var height = window.outerHeight
pan.width = width
pan.height = height
//绘画状态
let opts = {
"start": Math.PI * 1.5,
"end" : Math.PI * 3,
"color": "red"
}
/**
* 绘画圆弧
* @param options 配置文件
*/
function drawPie (opts) {
/**
* @param startAngle 开始弧度
* @param endAngle 结束弧度
* @param timeAngle 每次绘制的弧度的增量
* @param sumAngle 总的绘制的弧度
* @param initStartAngle 一开始弧度和总增量的和 用于判断是否绘画完成
* @param vDraw 绘制的速度 50ms
*/
var startAngle = opts.start,
endAngle = opts.end,
timeAngle,
sumAngle,
initStartAngle,
vDraw = 50;
sumAngle = startAngle - endAngle
if (sumAngle<0) {
sumAngle = -sumAngle
}
initStartAngle = opts.start + sumAngle
timeAngle = (sumAngle / 1000) * vDraw
var ctx = pan.getContext("2d")
// 弧度 = 角度 * Math.PI / 180
var timerHandle = setInterval(function () {
/**
* 应该获取到上次的结束的弧度,作为下次开始的弧度
**/
ctx.arc(width / 2, height /2, 50, opts.start, opts.start + timeAngle, false )
ctx.strokeStyle=opts.color
ctx.lineWidth= 40
ctx.stroke()
// 判断是否绘画到需要的点
if(initStartAngle >= opts.start + timeAngle) {
opts.start = opts.start + timeAngle
} else {
console.log('end')
clearInterval(timerHandle)
}
}, vDraw)
}
drawPie(opts)
</script>
</html>
后记:
这个只是个简单的demo,线条的优化等,还有定时函数的替代函数requestAnimationFrame,毕竟js是单线程,同时使用两个高触发的定时函数,是很危险的事情,一不小心就会照成浏览器卡顿。也可以使用worker技术,开启多线程。不过我也没有用worker技术