使用场景
项目上要用到一个圆环形的进度条,同时随着值的不同,颜色也不同,但是找了很多,都是水平进度条,或者径向渐变,不满足需求。
思路
canvas的api中已提供了两种,径向和线性渐变,并没有这种环形的渐变,所以很容易画出对称渐变。但是canvas提供了使用Pattern来绘制,Pattern可以是图片等其它对像,那么这里就使用到这个api,需要使用一张环形渐变的图像来绘制非对称渐变。
绘制对称环形渐变
这里使用的(水平)线性渐变。先使用createLinearGradient创建渐变,然后使用strokeStyle进行设置,然后使用stroke绘制。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| var canvas = document.getElementById("canvas"); var ctx = canvas.getContext('2d'); ctx.lineWidth = 5; ctx.beginPath(); ctx.moveTo(170, 120); var grd=ctx.createLinearGradient(0,0,170,0); grd.addColorStop("0","black"); grd.addColorStop("0.3","magenta"); grd.addColorStop("0.5","blue"); grd.addColorStop("0.6","green"); grd.addColorStop("0.8","yellow"); grd.addColorStop(1,"red"); ctx.strokeStyle = grd; ctx.arc(120, 120, 50, 0 ,Math.PI*2); ctx.stroke(); // 画圆
|
效果如下:
绘制非对称环形渐变
先使用ps制作一张环形渐变的图片。实现代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| var canvas = document.getElementById("canvas2"); var ctx2 = canvas.getContext('2d'); ctx2.lineWidth = 5; var img; img = new Image(); img.src = "./canvas.png"; if (img.complete) { setImageFill(); } else { img.onload = setImageFill; } var newFill = null; function setImageFill() { newFill = ctx2.createPattern(img, 'no-repeat'); ctx.beginPath(); ctx.strokeStyle = newFill; ctx.arc(50, 50, 46, 0, Math.PI*2, false); ctx.stroke(); }
|
效果如下:
效果已经基本上出现了,下面还需要让其动起来。
动态绘制
其实就是添加一个动态函数,在这里使用html5新添加的requestAnimationFrame,这个函数有兼容性的考虑,需要注意!这里不做处理!
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| var canvas = document.getElementById("canvas2"); var ctx2 = canvas.getContext('2d'); ctx2.lineWidth = 5; ctx2.lineCap="round"; var img; img = new Image(); img.src = "canvas.png"; if (img.complete) { setImageFill(); } else { img.onload = setImageFill; } var newFill = null; function setImageFill() { newFill = ctx2.createPattern(img, 'no-repeat'); drawCircle(ctx2, 0,50); } var stop = null ; function drawCircle(ctx, x, end) { ctx.clearRect(0, 0, 300, 300); ctx.beginPath(); ctx.strokeStyle = newFill; if (x < Math.PI*2*end/100) { x += Math.PI/100; } else { window.cancelAnimationFrame(stop) } ctx.arc(50, 50, 46, 0, x, false); ctx.stroke(); stop = requestAnimationFrame(function () { drawCircle(ctx, x ,end); }); }
|
其中的drawCircle第三个参数就是对应的值。
效果如下:
演示地址
点击演示
Github
本文地址:
http://wsdever.github.io/2016/08/13/20160813/