}#c{margin-top:20px;
}input[type=range]::before{content:attr(min);color:#000;padding-right:5px;}input[type=range]::after{content:attr(max);color:#000;padding-left:5px;}
当前浏览器不支持canvas 请升级!
let ctx=canvas.getContext("2d")
let oRange=document.getElementsByName("range")[0];
let M=Math
let Sin=M.sin
let Cos=M.cos
let Sqrt=M.sqrt
let Pow=M.pow
let PI=M.PI
let Round=M.round
let oW=canvas.width= 250let oH=canvas.height= 250let lineWidth= 2 //线宽
let r=(oW/ 2)//大半径
let cR=r- 10 *lineWidth
ctx.beginPath()
ctx.lineWidth=lineWidth//水波动画初始参数
let axisLength= 2 *r- 16 *lineWidth//Sin 图形长度
let unit=axisLength/ 9 //波浪宽
let range=.4 //浪幅
let nowrange=range
let xoffset= 8 *lineWidth//x 轴偏移量
let data= ~~(oRange.value)/ 100 //数据量
let sp= 0 //周期偏移量
let nowdata= 0let waveupsp= 0.006 //水波上涨速度
//圆动画初始参数
let arcStack=[]//圆栈
let bR=r- 8 *lineWidth
let soffset= -(PI/ 2)//圆动画起始位置
let circleLock= true //起始动画锁
//获取圆动画轨迹点集
for(vari=soffset; i
arcStack.push([
r+bR*Cos(i),
r+bR*Sin(i)
])
}//圆起始点
let cStartPoint=arcStack.shift();
ctx.strokeStyle= "#1c86d1";
ctx.moveTo(cStartPoint[0], cStartPoint[1]);//开始渲染
render();functiondrawSine() {
ctx.beginPath();
ctx.save();varStack=[];//记录起始点和终点坐标
for(vari=xoffset; i<=xoffset+axisLength; i+= 20 /axisLength) {varx=sp+(xoffset+i)/unit;vary=Sin(x)*nowrange;vardx=i;vardy= 2 *cR*(1 -nowdata)+(r-cR)-(unit*y);
ctx.lineTo(dx, dy);
Stack.push([dx, dy])
}//获取初始点和结束点
varstartP=Stack[0]varendP=Stack[Stack.length- 1]
ctx.lineTo(xoffset+axisLength, oW);
ctx.lineTo(xoffset, oW);
ctx.lineTo(startP[0], startP[1])
ctx.fillStyle= "#fbec99";
ctx.fill();
ctx.restore();
}functiondrawText() {
ctx.globalCompositeOperation= 'source-over';varsize= 0.4 *cR;
ctx.font= 'bold' +size+ 'px Microsoft Yahei';
let txt=(nowdata.toFixed(2)* 100).toFixed(0)+ '`%';varfonty=r+size/ 2;varfontx=r-size* 0.8;
ctx.fillStyle= "#f6b71e";
ctx.textAlign= 'center';
ctx.fillText(txt, r+ 5, r+ 20)
}//最外面淡黄色圈
functiondrawCircle() {
ctx.beginPath();
ctx.lineWidth= 15;
ctx.strokeStyle= '#fff89d';
ctx.arc(r, r, cR+ 7,0,2 *Math.PI);
ctx.stroke();
ctx.restore();
}//灰色圆圈
functiongrayCircle() {
ctx.beginPath();
ctx.lineWidth= 10;
ctx.strokeStyle= '#eaeaea';
ctx.arc(r, r, cR- 5,0,2 *Math.PI);
ctx.stroke();
ctx.restore();
ctx.beginPath();
}//橘黄色进度圈
functionorangeCircle() {
ctx.beginPath();
ctx.strokeStyle= '#fbdb32';//使用这个使圆环两端是圆弧形状
ctx.lineCap= 'round';
ctx.arc(r, r, cR- 5,0 *(Math.PI/ 180.0)-(Math.PI/ 2), (nowdata* 360)*(Math.PI/ 180.0)-(Math.PI/ 2));
ctx.stroke();
ctx.save()
}//裁剪中间水圈
functionclipCircle() {
ctx.beginPath();
ctx.arc(r, r, cR- 10,0,2 *Math.PI,false);
ctx.clip();
}//渲染canvas
functionrender() {
ctx.clearRect(0,0, oW, oH);//最外面淡黄色圈
drawCircle();//灰色圆圈
grayCircle();//橘黄色进度圈
orangeCircle();//裁剪中间水圈
clipCircle();//控制波幅
oRange.addEventListener("change",function() {
data= ~~(oRange.value)/ 100;
},0);if(data>= 0.85) {if(nowrange>range/ 4) {vart=range* 0.01;
nowrange-=t;
}
}else if(data<= 0.1) {if(nowrange
nowrange+=t;
}
}else{if(nowrange<=range) {vart=range* 0.01;
nowrange+=t;
}if(nowrange>=range) {vart=range* 0.01;
nowrange-=t;
}
}if((data-nowdata)> 0) {
nowdata+=waveupsp;
}if((data-nowdata)< 0) {
nowdata-=waveupsp
}
sp+= 0.07;//开始水波动画
drawSine();//写字
drawText();
requestAnimationFrame(render)
}