如何使用canvas绘制椭圆,扩展非chrome浏览器中的ellipse方法
这篇博文主要针对浏览器中绘制椭圆的方法扩展。在网上搜索了很多,发现他们绘制椭圆的方式都有缺陷。其中有压缩法,计算法,贝塞尔曲线法等多种方式。但是都不能很好的绘制出椭圆。所有我就对这个绘制椭圆的方式进行了研究,发现压缩法是可以完美实现椭圆绘制的。只不过很多人转发博文时根本不考虑事情的本质,人云亦云。废话不多说,直接上代码了。
1 if (!CanvasRenderingContext2D.prototype.ellipse) { 2 CanvasRenderingContext2D.prototype.ellipse = function(x, y, radiusX, radiusY, rotation, startAngle, endAngle, 3 anticlockwise) { 4 var r = radiusX > radiusY ? radiusX : radiusY; //用打的数为半径 5 var scaleX = radiusX / r; //计算缩放的x轴比例 6 var scaleY = radiusY / r; //计算缩放的y轴比例 7 var _x = x / scaleX, 8 _y = y / scaleY; //计算圆心位置 9 this.save(); //保存副本 10 this.translate(_x, _y); //移动到圆心位置 11 this.rotate(rotation); //进行旋转 12 this.scale(scaleX, scaleY); //进行缩放 13 this.arc(0, 0, r, startAngle, endAngle, anticlockwise); //绘制圆形 14 this.restore(); //还原副本 15 } 16 }
这里给解释一下别的博文里面中的压缩法为啥不正确.下面我抄袭别人一段代码,来解析一下为啥错误.
1 <!DOCTYPE html> 2 <html> 3 <head lang="en"> 4 <meta charset="UTF-8"> 5 <title>椭圆</title> 6 </head> 7 <body> 8 <canvas id="canvas" style="border:1px solid #aaa;display:block;margin:50px auto;"> 9 当前浏览器不支持Canvas,请更换浏览器后再试 10 </canvas> 11 <script> 12 var canvas = document.getElementById("canvas"); 13 canvas.width = 600; 14 canvas.height = 600; 15 var context = canvas.getContext("2d"); 16 context.lineWidth = 10; 17 context.strokeStyle="black"; 18 EvenCompEllipse(context, 130, 200, 100, 20); //椭圆 19 function EvenCompEllipse(context, x, y, a, b){ 20 context.save(); 21 //选择a、b中的较大者作为arc方法的半径参数 22 var r = (a > b) ? a : b; 23 var ratioX = a / r; //横轴缩放比率 24 var ratioY = b / r; //纵轴缩放比率 25 context.scale(ratioX, ratioY); //进行缩放(均匀压缩) 26 context.beginPath(); 27 //从椭圆的左端点开始逆时针绘制 28 context.moveTo((x + a) / ratioX, y / ratioY); 29 context.arc(x / ratioX, y / ratioY, r, 0, 2 * Math.PI); 30 context.closePath(); 31 context.stroke(); 32 context.restore(); 33 }; 34 </script> 35 </body> 36 </html>
他绘制的效果如下
为什么会出现这种情况呢.因为他在绘制的时候先绘制了,然后才还原.这样的话是压缩的一个路径,在绘制的时候就会连线条也进行压缩.而我的那段代码中并没有直接进行绘制.而是进行了还原操作.下面我给一段示例代码.大家可以直接进行试验.
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>canvas绘制椭圆</title> 6 </head> 7 <body> 8 <canvas id="canvas" width='500' height='500'></canvas> 9 <script> 10 if (!CanvasRenderingContext2D.prototype.ellipse) { 11 CanvasRenderingContext2D.prototype.ellipse = function(x, y, radiusX, radiusY, rotation, startAngle, endAngle, 12 anticlockwise) { 13 var r = radiusX > radiusY ? radiusX : radiusY; //用打的数为半径 14 var scaleX = radiusX / r; //计算缩放的x轴比例 15 var scaleY = radiusY / r; //计算缩放的y轴比例 16 var _x = x / scaleX, 17 _y = y / scaleY; //计算圆心位置 18 this.save(); //保存副本 19 this.translate(_x, _y); //移动到圆心位置 20 this.rotate(rotation); //进行旋转 21 this.scale(scaleX, scaleY); //进行缩放 22 this.arc(0, 0, r, startAngle, endAngle, anticlockwise); //绘制圆形 23 this.restore(); //还原副本 24 } 25 } 26 var ctx = document.getElementById("canvas").getContext("2d"); 27 ctx.beginPath(); 28 ctx.ellipse(300, 300, 150, 100, 30 * Math.PI / 180, 0, Math.PI * 2); 29 ctx.lineWidth = 10; //设定线宽为10 30 ctx.stroke(); 31 ctx.closePath(); 32 </script> 33 </body> 34 </html>
实际效果如下:
由此可见,其实压缩法是完全可以实现椭圆绘制的.只是大部分博文里面使用的都不太对而已.
如果觉得我这种方式不是你想要的的,也可以参考:https://www.cnblogs.com/fangsmile/p/9923532.html
如果 你觉得我的方式对的话,希望你能够进行转发.让更多的人知道这种绘制椭圆的方法.谢谢.
原文地址:https://www.cnblogs.com/flybeijing/p/canvas_ellipse.html