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