效果图
实现原理:
1.使用canvas绘制两个半圆弧,底图灰色半圆弧和颜色进度圆弧。
2.利用setInterval计时器,逐步改变颜色进度条,达到进度条的效果。
效果代码:

1 <!DOCTYPE html> 2 <html> 3 4 <head> 5 <meta charset="UTF-8"> 6 <title></title> 7 </head> 8 9 <body> 10 <canvas id="canvas" width="300" height="300"> 11 </canvas> 12 13 <script type="text/javascript"> 14 function toCanvas(id, progress, progress2) { 15 //canvas进度条 16 var canvas = document.getElementById(id), 17 ctx = canvas.getContext("2d"), 18 percent = progress, 19 percent2 = progress2, 20 //最终百分比 21 circleX = canvas.width / 2, // 中心x坐标 22 circleY = canvas.height / 2, //中心y坐标 23 radius = 100, //圆环半径 24 lineWidth = 8, // 圆形线条的宽度 25 fontSize = 10; //字体大小 26 27 /*//两端圆点 28 function smallcircle1(cx, cy, r) { 29 ctx.beginPath(); 30 ctx.lineWidth = 1; 31 ctx.fillStyle = '#06a8f3'; 32 ctx.arc(cx, cy, r, Math.PI, Math.PI * 2); 33 ctx.fill(); 34 } 35 36 function smallcircle2(cx, cy, r) { 37 ctx.beginPath(); 38 ctx.lineWidth = 1; 39 ctx.fillStyle = '#00f8bb'; 40 ctx.arc(cx, cy, r, Math.PI, Math.PI * 2); 41 ctx.fill(); 42 }*/ 43 44 //画圆 45 function circle(cx, cy, r) { 46 ctx.beginPath(); 47 ctx.lineWidth = lineWidth; 48 ctx.strokeStyle = '#eee'; 49 ctx.arc(cx, cy, r, Math.PI, Math.PI * 2); 50 //ctx.arc(cx, cy, r, Math.PI * 2 / 3, Math.PI * 1 / 3); 51 ctx.stroke(); 52 } 53 54 //画弧线 55 function sector(cx, cy, r, startAngle, endAngle, anti) { 56 ctx.beginPath(); 57 ctx.lineWidth = lineWidth; 58 59 // 渐变色 - 可自定义 60 var linGrad = ctx.createLinearGradient( 61 circleX - radius - lineWidth, circleY, circleX + radius + lineWidth, circleY 62 ); 63 linGrad.addColorStop(0.0, '#06a8f3'); 64 linGrad.addColorStop(1.0, '#00f8bb'); 65 ctx.strokeStyle = linGrad; 66 //圆弧两端的样式 67 ctx.lineCap = 'round'; 68 ctx.arc(cx, cy, r, Math.PI, Math.PI * (1 + endAngle / 100)); 69 ctx.stroke(); 70 } 71 72 //画弧线02 73 function sector2(cx, cy, r, startAngle, endAngle, anti) { 74 ctx.beginPath(); 75 ctx.lineWidth = lineWidth; 76 77 // 渐变色 - 可自定义 78 var linGrad = ctx.createLinearGradient( 79 circleX - radius - lineWidth, circleY, circleX + radius + lineWidth, circleY 80 ); 81 linGrad.addColorStop(0.0, '#06a8f3'); 82 linGrad.addColorStop(1.0, '#00f8bb'); 83 ctx.strokeStyle = linGrad 84 85 //圆弧两端的样式 86 ctx.lineCap = 'round'; 87 ctx.arc(cx, cy, r * 3 / 4, Math.PI, Math.PI * (1 + endAngle / 100)); 88 ctx.stroke(); 89 } 90 //刷新 91 function loading() { 92 var percent3 = progress; 93 if(percent < percent2) percent = percent2; 94 if(process >= percent) clearInterval(circleLoading); 95 if(process2 >= percent) clearInterval(circleLoading); 96 //清除canvas内容 97 ctx.clearRect(0, 0, circleX * 2, circleY * 2); 98 99 //中间的字 100 ctx.font = fontSize + 'px April'; 101 ctx.textAlign = 'center'; 102 ctx.textBaseline = 'middle'; 103 ctx.fillStyle = '#999'; 104 ctx.fillText(parseFloat(process).toFixed(0) + '%', circleX, circleY*4/5); 105 ctx.fillText("月度完成比",circleX, circleY); 106 107 //圆形 108 circle(circleX, circleY, radius); 109 110 //圆弧 111 sector(circleX, circleY, radius, Math.PI * 2 / 3, process); 112 sector2(circleX, circleY, radius, Math.PI * 2 / 3, process2); 113 //两端圆点 114 //smallcircle1(50 + Math.cos(2 * Math.PI / 360 * 120) * 100, 150 + Math.sin(2 * Math.PI / 360 * 120) * 100, 5); 115 //smallcircle2(50 + Math.cos(2 * Math.PI / 360 * (120 + process * 3)) * 100, 150 + Math.sin(2 * Math.PI / 360 * (120 + process * 3)) * 100, 5); 116 //控制结束时动画的速度 117 if(process < percent3) { 118 if(process / percent > 0.90) { 119 process += 0.30; 120 } else if(process / percent > 0.80) { 121 process += 0.55; 122 } else if(process / percent > 0.70) { 123 process += 0.75; 124 } else { 125 process += 1.0; 126 } 127 } 128 129 if(process2 < percent2) { 130 if(process2 / percent > 0.90) { 131 process2 += 0.30; 132 } else if(process2 / percent > 0.80) { 133 process2 += 0.55; 134 } else if(process2 / percent > 0.70) { 135 process2 += 0.75; 136 } else { 137 process2 += 1.0; 138 } 139 } 140 141 } 142 143 var process = 0.0; 144 var process2 = 0.0; 145 146 var circleLoading = window.setInterval(function() { 147 loading(); 148 }, 20); 149 150 } 151 toCanvas('canvas', 50, 80); 152 </script> 153 </body> 154 155 </html>