使用场景

使用html5的canvas写的一个类似360清理大师那样的球形清理进度条,如下图所示



绘制过程

画外边的白色圆框
1
2
3
ctx.arc(250, 250, 100, 0, Math.PI * 2, false);
ctx.strokeStyle = '#fff';
ctx.lineWidth = "10";
画里面的红色圆
1
2
3
ctx.arc(250, 250, 100, 0, Math.PI * 2, false);
ctx.fillStyle = "red";
ctx.fill();
画下面的绿色部分
1
2
3
4
5
6
7
var ac = (r - n * (2*r/10)) / r ;
var ang1 = Math.asin(ac) ;
var ang2 = Math.PI - ang1 ;
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.arc(250, 250, 100, ang1, ang2 , false);

但这只能画出一个水平的,其中r为半径,n为当前的进度转化成 10 以内的数,比如80%,对应着 8 。
要画出下面波浪,还需要在下方使用一条二次贝塞尔曲线对路径进行封闭,并使用由下向上的线性渐变进行填充。

1
2
3
4
5
ctx.bezierCurveTo(cx1,cy1,cx2,cy2,ex,by);
var landStyle = ctx.createLinearGradient(250 ,250 + 1.2*r ,250,250 - 1.2*r);
landStyle.addColorStop(0,"#580");
landStyle.addColorStop(1,"#030");
ctx.fillStyle = landStyle;

动态画进度数字
1
2
3
4
5
6
7
ctx.beginPath();
txt = n * 10 + '%';
ctx.font="30px Verdana";
ctx.lineWidth = "1";
ctx.clearRect(250 - 0.35*r , 250 + 1.5 * r - 30, 100, 40);
ctx.fillStyle = "#fff" ;
ctx.fillText(txt,250 - 0.35*r , 250 + 1.5*r);

至此四步,一个水晶进度就画完了,自己也可以再做些美化,基本思路就是这样。重点是对贝塞尔曲线的位置计算。

演示地址:

GitHub地址:

本文地址: http://wsdever.github.io/2016/09/10/20160910/