将SVG ARCTO映射到HTML Canvas ARCTO


SVG specification中的ARCTO与我们在
Canvas中的完全不同.我有一个用例,我将根据SVG规范获得数据,但我需要在Canvas上绘制它.

我尝试了这个,但我想我的几何形状很弱.你能帮忙吗?

最佳答案 svg ellipse和canvas arc之间的区别在于svg中有2个半径,arcTo中只有1个半径.然后,您还需要在画布中以特定角度旋转圆弧.要模拟2个半径,您需要使用给定坐标具有最小半径的圆弧.然后,您需要使用系数(rx / ry)在特定方向上缩放此弧.而现在你只需要旋转.但是在这种方法中很难说明你要显示的椭圆的哪个部分,因为它取决于svg规范中的大弧标志和扫描标志.另一个问题是通过结束坐标(来自svg规范)限制弧.所以通过arcTo,我猜你可以建立一个椭圆的一半.

如果椭圆上有3个控制点的坐标,也可以使用bezierCurveTo(x0,y0,x1,y1,x2,y2)绘制椭圆的一部分.使用这种方法,您可以构建椭圆的任何部分.当然,对于超过PI的段,您将需要至少两条曲线

从你有SVG规范(rx ry x轴旋转大弧标志扫描标志x y).所以样本路径就是这样的:

  M100,100 a25,50 -30 0,1 50,-25

Here你可能会发现应该如何绘制贝塞尔曲线.

现在你有一个上下文点(100,100)和一个终点(100 50,100-25)
您需要在旋转到-30度之前计算控制点.

这是一个适合我的例子:

$(document).ready(function(){
        var startX = 100;
        var startY = 100;
        var dX = 50;
        var dY = -25;
        var angle = -30;
        var rx = 25;
        var ry = 50;
        var svg = Raphael($('#svg')[0], 200, 200);

        var path = "M" +startX + "," + startY + " a" + rx + "," + ry + " " + angle + " 0,1" + " " + dX + "," +dY;
        svg.path(path).attr({"stroke-width" : 2, "stroke" : "#FFFFFF"});

        var kappa = .5522848,
        ox = rx*kappa,
        oy = ry*kappa,
        xm = startX + rx,       // x-middle
        ym = startY + ry;       // y-middle
        var canvas = document.getElementById("canvas");
        var ctx = canvas.getContext("2d");
        ctx.moveTo(startX,startY);
        ctx.bezierCurveTo(startX, startY - oy, startX + ox, startY - ry, startX + rx, startY - ry);
        ctx.bezierCurveTo(startX + rx + ox, startY - ry, startX + 2*rx, startY - oy, startX + dX, startY + dY);
        ctx.stroke();
    });

标记很简单:

<div id="svg" style="border: 1px solid black;position : absolute;top : 50px;left : 50px;"></div>
<canvas id="canvas" width="200px" height="200px" style="border: 1px solid black;position : absolute;top : 300px;left : 50px;"></canvas>

曲线不相似,因为我没有将控制点旋转到-30度.但我相信这是你唯一需要做的事情.因为如果你将角度= 0,它们将是相似的
您可以使用this文章来获取轮换数学.

PS:我从this回答了部分代码

点赞