本文属于《html5 Canvas画图系列教程》
画扇形这个事儿,貌似不应该拖到现在讲,因为这明显跟前面几章“画圆形,画矩形”是一路的,但我拖到现在才讲是有理由的,因为画扇形需要用到我上两章讲的知识。
扇形,就是一个不完整的圆,提到圆,我们就能马上想到用arc方法来画。的确,arc可以画出扇形的弧线,但光是靠arc我们是不能画出扇形的,下面是一个扇形和一个不完整的圆弧:
抱歉,画得很粗略,但他们的区别还是很容易就看出来了。
如果我们不使用上两章讲的画面位移旋转与还原,那么画扇形就会让人头大无比。一个扇形,包含圆心,半径,起始与终止的角度,最后还要从圆心分别连接到起止点才行。
我先写一个初步的画扇形的函数:
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 | //扇形 CanvasRenderingContext2D.prototype.sector = function (x, y, radius, sDeg, eDeg) { // 初始保存 this.save(); // 位移到目标点 this.translate(x, y); this.beginPath(); // 画出圆弧 this.arc(0,0,radius,sDeg, eDeg); // 再次保存以备旋转 this.save(); // 旋转至起始角度 this.rotate(eDeg); // 移动到终点,准备连接终点与圆心 this.moveTo(radius,0); // 连接到圆心 this.lineTo(0,0); // 还原 this.restore(); // 旋转至起点角度 this.rotate(sDeg); // 从圆心连接到起点 this.lineTo(radius,0); this.closePath(); // 还原到最初保存的状态 this.restore(); return this; } |
代码中已经有详细注释,但我还要说几句。函数中画路径的时候,就先画弧线,再从终点连到圆心,再从圆心连到起点。为什么?因为这个顺序路径才不会断——arc是从起点开始画起的,最后路径又回到起点,才合情合理。在测试函数的时候,我想当然的先画了弧线,再从起点连圆心连终点,结果导致路径断了。大家一定要注意。
此函数是附加于原型的,所以大家使用时可以这么用:
1 2 | var ctx = document.getElementById('cvs').getContext('2d'); ctx.sector(100,100,50,0,Math.PI/180*230).fill(); |
这样你就能画出如下的扇形:
此函数写得比较粗略,以后可能会改进。也希望你能提出意见。
下面我们用上面的画扇形函数来画一个分饼统计图吧:
1 2 3 4 5 6 7 8 9 10 11 12 | var deg = Math.PI/180; ctx.sector(100,100,80,30*deg,111*deg).fill(); ctx.fillStyle="#f00"; ctx.sector(100,100,80,111*deg,190*deg).fill(); ctx.fillStyle="#0f0"; ctx.sector(100,100,80,190*deg,233*deg).fill(); ctx.fillStyle="#00f"; ctx.sector(100,100,80,233*deg,280*deg).fill(); ctx.fillStyle="#789"; ctx.sector(100,100,80,280*deg,345*deg).fill(); ctx.fillStyle="#abcdef"; ctx.sector(100,100,80,345*deg,30*deg).fill(); |
最终效果如图所示:
当然,实际上你可以用一个循环来搞定这个饼图,因为他们的位置,半径都是一样的,只是起止点不同。
大家可以思考一下不用位移与旋转的画法,不过真的是有点蛋疼。
不理解你为什么rotate两次,感觉好奇怪
为什么没效果
。。。
把颜色也传进去就方便了
好
完全不需要这么麻烦,设置起点在圆心,最后闭合路径就可以了:http://www.clanfei.com/2014/12/1745.html
要考虑扇形的角度问题呢
太感谢了,你的方法简洁明多了!
不懂调用的参数什么意思,能不能说明白一些
里面的参数太多了,建议你一步步来,了解每个方法是干什么的再说
里面的参数太多了,建议你一步步来,了解每个方法是干什么的再说