這篇博文主要針對瀏覽器中繪制橢圓的方法擴展。在網上搜索了很多,發現他們繪制橢圓的方式都有缺陷。其中有壓縮法,計算法,貝塞爾曲線法等多種方式。但是都不能很好的繪制出橢圓。所有我就對這個繪制橢圓的方式進行了研究,發現壓縮法是可以完美實現橢圓繪制的。廢話不多說,直接上代碼了。
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軸比例 this.save(); //保存副本 this.translate(x, y); //移動到圓心位置 this.rotate(rotation); //進行旋轉 this.scale(scaleX, scaleY); //進行縮放 this.arc(0, 0, r, startAngle, endAngle, anticlockwise); //繪制圓形 this.restore(); //還原副本 } }
這里給解釋一下別的博文里面中的壓縮法為啥不正確.下面我抄襲別人一段代碼,來解析一下為啥錯誤.
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>
他繪制的效果如下
為什么會出現這種情況呢.因為他在繪制的時候先繪制了,然后才還原.這樣的話是壓縮的一個路徑,在繪制的時候就會連線條也進行壓縮.而我的那段代碼中並沒有直接進行繪制.而是進行了還原操作.下面我給一段示例代碼.大家可以直接進行試驗.
<!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軸比例 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