HTML结构
首先先构造一个div结构,里面放一个canvas和调节范围的结构(input[type="range"])。
<div id="app">
<canvas id="canvas" width="200" height="200" ></canvas>
<input type="range" id="range" value="0">
</div>
CSS结构
运用绝对定位的方式将canvas画布进行居中,还有进度条设置也居中并把它放在canvas画布下面。
#app
{
position: relative;
height: 100vh;
}
#app #canvas
{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
}
#app #range
{
position: absolute;
top: 80%;
left: 50%;
transform: translate(-50%,0);
}
JavaScript结构
接下来就是最重要的JavaScript结构了,主要使用了一些圆的函数进行解决。
var range = document.getElementById("range");
var canvas = document.getElementById("canvas");
var cxt = canvas.getContext("2d");
var cenX = canvas.width/2;
var cenY = canvas.height/2;
var progress = Math.PI*2/100;
var steps=0;
function DrawPro(cxt,steps){
//绘制进度环
cxt.clearRect(0,0,canvas.width,canvas.height);
cxt.strokeStyle = "#dddddd";
cxt.lineWidth=20;
cxt.save();
cxt.beginPath();
cxt.arc(cenX,cenY,90,0,Math.PI*2,false);
cxt.stroke();
cxt.closePath();
cxt.restore();
cxt.fillStyle="rgb(247,213,0)"
cxt.save();
cxt.beginPath();
cxt.arc(cenX,cenY,80,0,Math.PI*2,false);
cxt.fill();
cxt.closePath();
cxt.restore();
cxt.strokeStyle="skyblue";
cxt.lineWidth=20;
cxt.save();
cxt.beginPath();
cxt.arc(cenX,cenY,90,-Math.PI/2,-Math.PI/2+steps*progress,false);
cxt.stroke();
cxt.closePath();
cxt.restore();
//绘制字体
cxt.fillStyle="#000000";
cxt.font="bold 26px Poppin";
cxt.save();
cxt.beginPath();
//考虑了数字的个数 如果是100三位数字的位置和两位数字
if(steps.toFixed(0).length==3){
cxt.fillText(steps.toFixed(0)+"%",cenX-30,cenY+10);
}else if(steps.toFixed(0).length==1){
cxt.fillText(steps.toFixed(0)+"%",cenX-17,cenY+10);
}else{
cxt.fillText(steps.toFixed(0)+"%",cenX-22,cenY+10);
}
cxt.closePath();
cxt.restore();
//动态进度小球
cxt.fillStyle="white";
cxt.save();
cxt.beginPath();
cxt.arc(90*Math.cos(Math.PI/2-(Math.PI*2*(steps/100)))+100,90*-Math.sin(Math.PI/2-(Math.PI*2*(steps/100)))+100,10,0,Math.PI*2,false);
cxt.fill();
cxt.closePath();
cxt.restore();
//静态进度小球
cxt.fillStyle="white";
cxt.save();
cxt.beginPath();
cxt.arc(100,10,10,0,Math.PI*2,false);
cxt.fill();
cxt.closePath();
cxt.restore();
}
DrawPro(cxt,steps);
range.addEventListener("input",()=>{
steps = parseInt(range.value);
DrawPro(cxt,steps);
console.log(90*Math.cos(Math.PI/2-(Math.PI*2*(steps/100)))+100,90*-Math.sin(Math.PI/2-(Math.PI*2*(steps/100)))+100)
})