多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
看示例之前,先看一下简单五角星的绘制。 ![](https://box.kancloud.cn/860849937b683ca42f32e56c772b48e7_400x387.jpg) ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>五角星进度</title> </head> <body> <canvas id="cvs"></canvas> <script> var cvs = document.getElementById('cvs'); cvs.width = 500; cvs.height = 500; cvs.style.backgroundColor = '#eee'; var ctx = cvs.getContext('2d'); ctx.beginPath(); ctx.moveTo(76,197); ctx.lineTo(421,197); ctx.lineTo(143,399); ctx.lineTo(248,71); ctx.lineTo(356,399); ctx.lineTo(76,197); ctx.closePath(); ctx.lineWidth = 8; ctx.stroke(); ctx.fillStyle = '#ccc'; ctx.fill(); </script> </body> </html> ~~~ 注意:先stroke后fill才能把五角星里面的连接覆盖掉。 下面看下示例效果 ![](https://box.kancloud.cn/9a6f47175654988cdf62606115bbe392_388x364.gif) 代码 ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>五角星进度</title> </head> <body> <canvas id="cvs"></canvas> <script> var cvs = document.getElementById('cvs'); cvs.width = 500; cvs.height = 500; cvs.style.backgroundColor = '#eee'; var ctx = cvs.getContext('2d'); // 数据 var initPoint = [76, 197]; // 初始点 var pointsArr = [ // 连接点 [421, 197], [143, 399], [248, 71], [356, 399], [76, 197], ]; var pointsSize = pointsArr.length; // 连接点数量 var segmentPercent = Math.round(100/pointsSize); // 每个点占的百分比 var percent = 0; function progressStar() { if(percent <= 100) { var wholeSegmentIndex = Math.floor(percent/100*pointsSize); // 当前百分比能用的索引 var restPercent = percent%segmentPercent; // 取余百分比 var restPartPercent = restPercent/segmentPercent; // 取余百分比 点 每个点占的百分比 的百分比 var progressPointsArr = []; // 存乘余百分比的点 if(restPercent !== 0) { if(wholeSegmentIndex === 0) { progressPointsArr[0] = initPoint; progressPointsArr[1] = [ initPoint[0]+(pointsArr[0][0]-initPoint[0])*restPartPercent, initPoint[1]+(pointsArr[0][1]-initPoint[1])*restPartPercent ]; } else { progressPointsArr[0] = pointsArr[wholeSegmentIndex-1]; progressPointsArr[1] = [ pointsArr[wholeSegmentIndex-1][0]+(pointsArr[wholeSegmentIndex][0]-pointsArr[wholeSegmentIndex-1][0])*restPartPercent, pointsArr[wholeSegmentIndex-1][1]+(pointsArr[wholeSegmentIndex][1]-pointsArr[wholeSegmentIndex-1][1])*restPartPercent ]; } } // 清空 ctx.clearRect(0, 0, 500, 500); // 原图 ctx.save(); ctx.beginPath(); ctx.moveTo(initPoint[0], initPoint[1]); pointsArr.forEach(function(v) { ctx.lineTo(v[0], v[1]); }); ctx.closePath(); ctx.lineWidth = 8; ctx.stroke(); ctx.fillStyle = '#ccc'; ctx.fill(); ctx.restore(); // 进度图 ctx.save(); ctx.beginPath(); ctx.moveTo(initPoint[0], initPoint[1]); pointsArr.slice(0, wholeSegmentIndex).forEach(function(v) { ctx.lineTo(v[0], v[1]); }); // 是否关闭路径 if(percent === 100) { ctx.closePath(); } // 接点绘制 if(progressPointsArr.length > 0) { ctx.moveTo(progressPointsArr[0][0], progressPointsArr[0][1]); ctx.lineTo(progressPointsArr[1][0], progressPointsArr[1][1]); } ctx.lineWidth = 8; ctx.strokeStyle = '#690'; ctx.stroke(); // 是否填充 if(percent === 100){ ctx.fillStyle = '#ccc'; ctx.fill(); } ctx.restore(); window.requestAnimationFrame(progressStar); } percent++; } progressStar(); </script> </body> </html> ~~~ 主要的难点就是生成两坐标点之间的百分比坐标点 算法如下 ~~~ var p1 = [ 2, 2 ], p2 = [ 10, 10 ]; var percent = 0.6; var point = [ p1[0] + (p2[0] - p1[0]) * percent, p1[1] + (p2[1] - p1[1]) * percent ]; ~~~ 详情请参数,算法一节里的几何算法。。 ![](https://box.kancloud.cn/8b7ad6384c709ab48d5d500bf0222c41_226x177.jpg) > see you next time.