目录效果图思考实现思路具体代码实现效果图 思考 移动端的场景里经常会出现环形进度条的功能,在实现这个功能前,我预想的解决方案大致有: echarts、antv、canvas、svg
移动端的场景里经常会出现环形进度条的功能,在实现这个功能前,我预想的解决方案大致有: echarts、antv、canvas、svg
前面两种第三方提供的解决方案当然是简单,拿到案例修整一下即可,但是需要下载依赖,而且代码量不小。有没有不需要依赖第三方包,采用原生的写法,独立封装成一个组件,降低耦合,而且性能优越?
当然,那就主要介绍canvas的使用
可以展示整个圆、半圆以及任意角度弧形(左右对称)的进度条。整体思路如下:
1.先确定展示的形状,是整个圆、半圆还是一般的弧形
2.把确定好形状的圆弧均分100等份,计算出每一份所占的弧度
3.灰色圆弧占100份,红色圆弧最终占的份数由参数确定
4.设置setInterval定时器,重复执行画图操作
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-Scalable=no">
<title>Canvas</title>
</head>
<body>
<canvas id="canvas" width="300" height="300"></canvas>
<script>
draw(66);
function draw(percent, sR) {
if (percent < 0 || percent > 100) {
return;
}
if (sR < Math.PI/2 || sR >= 3/2 * Math.PI) {
return;
}
var canvas = document.querySelector('#canvas'),
cxt = canvas.getContext('2d'),
cWidth = canvas.width,
cHeight = canvas.height,
baseColor = '#e1e1e1',
coverColor = '#fe4d43',
PI = Math.PI,
sR = sR || 1/2 * PI; // 默认圆弧的起始点弧度为π/2
var finalRadian = sR + ((PI + (PI - sR) * 2) * percent / 100); // 红圈的终点弧度
var step = (PI + (PI - sR) * 2)/100; // 一个1%对应的弧度大小
var text = 0; // 显示的数字
var timer = setInterval(function() {
cxt.clearRect(0, 0, cWidth, cHeight);
var endRadian = sR + text * step;
// 画灰色圆弧
drawCanvas(cWidth/2, cHeight/2, 80, sR, sR + (PI + (PI - sR) * 2), baseColor, 2);
// 画红色圆弧
drawCanvas(cWidth/2, cHeight/2, 80, sR, endRadian, coverColor, 2);
// 画红色圆头
// 红色圆头其实就是一个圆,关键的是找到其圆心,涉及到三角函数知识,自己画个图一看就明了
var angle = 2*PI - endRadian; // 转换成逆时针方向的弧度(三角函数中的)
xPos = Math.cos(angle) * 80 + cWidth/2; // 红色圆 圆心的x坐标
yPos = -Math.sin(angle) * 80 + cHeight/2; // 红色圆 圆心的y坐标
drawCanvas(xPos, yPos, 2, 0, 2*PI, coverColor, 2);
// 数字
cxt.fillStyle = coverColor;
cxt.font = '40px PT Sans';
var textWidth = cxt.measureText(text+'%').width;
cxt.fillText(text+'%', cWidth/2 - textWidth/2, cHeight/2 + 15);
text++;
if (endRadian.toFixed(2) >= finalRadian.toFixed(2)) {
clearInterval(timer);
}
}, 30);
function drawCanvas(x,y,r,sRadian,eRadian,color,lineWidth) {
cxt.beginPath();
cxt.lineCap = "round";
cxt.strokeStyle = color;
cxt.lineWidth = lineWidth;
cxt.arc(x, y, r, sRadian, eRadian, false);
cxt.stroke();
}
}
</script>
</body>
</html>
关于动画部分,可以使用requestAnimationFrame
做优化,函数改写如下:
function draw(percent, sR) {
if (percent < 0 || percent > 100) {
return;
}
if (sR < Math.PI/2 || sR >= 3/2 * Math.PI) {
return;
}
var canvas = document.querySelector('#canvas'),
cxt = canvas.getContext('2d'),
cWidth = canvas.width,
cHeight = canvas.height,
baseColor = '#e1e1e1',
coverColor = '#fe4d43',
PI = Math.PI,
sR = sR || 1/2 * PI; // 默认圆弧的起始点弧度为π/2
var finalRadian = sR + ((PI + (PI - sR) * 2) * percent / 100); // 红圈的终点弧度
var step = (PI + (PI - sR) * 2)/100; // 一个1%对应的弧度大小
var text = 0; // 显示的数字
window.requestAnimationFrame(paint);
function paint() {
cxt.clearRect(0, 0, cWidth, cHeight);
var endRadian = sR + text * step;
// 画灰色圆弧
drawCanvas(cWidth/2, cHeight/2, 80, sR, sR + (PI + (PI - sR) * 2), baseColor, 2);
// 画红色圆弧
drawCanvas(cWidth/2, cHeight/2, 80, sR, endRadian, coverColor, 2);
// 画红色圆头
// 红色圆头其实就是一个圆,关键的是找到其圆心,涉及到三角函数知识,自己画个图一看就明了
var angle = 2*PI - endRadian; // 转换成逆时针方向的弧度(三角函数中的)
xPos = Math.cos(angle) * 80 + cWidth/2; // 红色圆 圆心的x坐标
yPos = -Math.sin(angle) * 80 + cHeight/2; // 红色圆 圆心的y坐标
drawCanvas(xPos, yPos, 2, 0, 2*PI, coverColor, 2);
// 数字
cxt.fillStyle = coverColor;
cxt.font = '40px PT Sans';
var textWidth = cxt.measureText(text+'%').width;
cxt.fillText(text+'%', cWidth/2 - textWidth/2, cHeight/2 + 15);
text++;
if (endRadian.toFixed(2) < finalRadian.toFixed(2)) {
window.requestAnimationFrame(paint);
}
}
function drawCanvas(x,y,r,sRadian,eRadian,color,lineWidth) {
cxt.beginPath();
cxt.lineCap = "round";
cxt.strokeStyle = color;
cxt.lineWidth = lineWidth;
cxt.arc(x, y, r, sRadian, eRadian, false);
cxt.stroke();
}
到此这篇关于详解javascript+Canvas绘制环形进度条的文章就介绍到这了,更多相关JavaScript Canvas环形进度条内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
--结束END--
本文标题: 详解JavaScript+Canvas绘制环形进度条
本文链接: https://lsjlt.com/news/138909.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-01-12
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0