canvas 实现环形进度条
效果
代码
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext("2d");
/**
* @author xie xiu yue
* @licence MIT
* @description https://juejin.cn/post/6844904056658329613
*/
/**
* 绘制圆形进度条
* @param {number} angle
* @param {number} x
* @param {number} y
* @param {number} radius
* @param {Object} option
*/
var drawRoundProgress = (ctx, angle, x, y, radius, option) => {
/**
* 绘制单个圆形进度
* @param {Object} o
*/
var drawCircle = (o) => {
var ctx = o.ctx
ctx.beginPath();
ctx.lineWidth = o.lineWidth
ctx.arc(o.x, o.y, o.radius, 1.5 * Math.PI, (1.5 + (o.angle * 2)) * Math.PI,false);
ctx.lineCap = 'round';
ctx.strokeStyle = o.color
ctx.stroke();
ctx.closePath();
}
drawCircle({
ctx,
angle: 1,
color: option.layerColor,
lineWidth: 3,
x: x + radius,
y: y + radius,
radius,
})
drawCircle({
ctx,
angle,
color: option.fill,
lineWidth: 6,
x: x + radius,
y: y + radius,
radius,
})
}
// 应用
drawRoundProgress(ctx, 10 / 100, roundY + rem(101), roundX + rem(608), rem(162) / 2, {
layerColor: '#1F67A5',
fill: '#FFDF00',
})
代码解析
核心就是ctx.arc函数
ctx.arc(o.x, o.y, o.radius, 1.5 * Math.PI, (1.5 + (o.angle * 2)) * Math.PI,false);
前两个是中心坐标 也就是 x和y
第三个是半径
第三个和第四个是开始和结束的角度
最后是是否顺时针
牛刀小试
了解了核心,那么我们来试试实现上面的效果。
var drawCircle = (o) => {
ctx.beginPath();
ctx.lineWidth = o.lineWidth
ctx.arc(o.x, o.y, o.radius, 0, Math.PI * 0.5,false);
ctx.strokeStyle = o.color
ctx.stroke();
ctx.closePath();
}
drawCircle({
angle: 0.1,
color: '#FFDF00',
lineWidth: 6,
x: 50,
y: 50,
radius: 30,
})
运行结果
???
怎么不太对,圆角哪里去了,起点怎么变成右方。
圆角
既然核心函数没有圆角,那么就是别的地方设置。
找女朋友一样找就可以找到
ctx.lineCap = 'round';
这行代码,加上去后就有了圆角。
但是起点不太对啊。效果图是从顶部开始。
角度问题
这时候我们需要看下面这张宝图
开始的角度
可以看到。0是在右方,而1.5才是开始,于是我们先设置开始为 1.5 * Math.PI
有了开始,我们需要结束
结束的角度设置
因为开始是1.5。于是需要设置偏移量1.5,但是这时候我们发现一圈是2,这样不好计算,于是需要转成1,等下方便传入百分比,于是这样写
(1.5 + (angle * 2)) * Math.PI
现在angle是多少,我们就会正确显示
所以代码
再次牛刀小试
ctx.arc(o.x, o.y, o.radius, 1.5 * Math.PI, (1.5 + (o.angle * 2)) * Math.PI,false);
好,完美。
--完--