zoukankan      html  css  js  c++  java
  • 如何使用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轴比例
            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

  • 相关阅读:
    2030
    2019
    2018
    在 《检验反相能力, 一题不会者 不配反相》 里 的 回复
    我转载了 历史吧 的 一个 帖 《为什么很多人说中国古代没有科学?这不扯淡嘛》 到 反相吧
    在 简单的数学题也不会做了。做一算术题,看看是否老年痴呆! 里 的 回复
    谈谈 光速
    相对论 的 时空观 本身 就会 导致 一个 绝对 的 参照系
    对 薛定谔 波函数, 我 关心 它的 推导依据, 不太关心 数学形式
    霍奇猜想 (二)
  • 原文地址:https://www.cnblogs.com/flybeijing/p/canvas_ellipse.html
Copyright © 2011-2022 走看看