用SVG的圆弧path绘制圆图

下面的SVGpath可以画出99.99%的圆:(在http://jsfiddle.net/DFhUF/46/上试一下,看看你是否看到4个弧或者只有2个,但是请注意,如果它是IE,就会呈现在VML中,不是SVG,但有类似的问题)

M 100 100 a 50 50 0 1 0 0.00001 0 

但是当它是99.99999999%的一个圆时,什么都不会显示出来?

 M 100 800 a 50 50 0 1 0 0.00000001 0 

这与100%的圆相同(它仍然是一个圆弧,是不是,只是一个非常完整的圆弧)

 M 100 800 a 50 50 0 1 0 0 0 

这怎么解决? 原因是我用一个函数来绘制一个弧的百分比,如果我需要用“特殊情况”一个99.9999%或100%的弧来使用这个圆的函数,那就太傻了。

同样,使用RaphaelJS的jsfiddle的testing用例在http://jsfiddle.net/DFhUF/46/
(如果是IE 8上的VML,即使是第二个圆也不会显示…您必须将其更改为0.01)


更新:

这是因为我在我们的系统中渲染了一个分数的弧,所以3.3分得到1/3的一个圆。 0.5圈半圈,9.9圈圈达到99%。 但是如果我们的系统中有9.99的分数呢? 我是否要检查它是否接近圆的99.999%,并相应地使用arc函数或circle函数? 那么9.9987的分数呢? 哪一个使用? 想要知道什么样的分数会映射到一个“太圆的圆圈”并切换到一个圆圈函数,当它是一个圆的“99.9%”或9.9987的分数时,那么使用弧函数是荒谬的。

XAML的弧线也一样。 只需用Zclosures99.99%的弧线,你就有了一个圆圈!

我知道游戏有点晚了,但是我从新的时候就想起了这个问题,而且我也有类似的困境,而且我偶然发现了“正确”的解决scheme,如果有人还在寻找:

 <path d=" M cx cy m -r, 0 ar,r 0 1,0 (r * 2),0 ar,r 0 1,0 -(r * 2),0 " /> 

换句话说,这个:

 <circle cx="100" cy="100" r="75" /> 

可以做到这样一条路:

  <path d=" M 100, 100 m -75, 0 a 75,75 0 1,0 150,0 a 75,75 0 1,0 -150,0 " /> 

诀窍是有两个弧,第二个拿起第一个离开的位置,并使用负直径返回到原始弧开始点。

在一个圆弧中不能完成一个圆的原因(我只是猜测)是因为你会告诉它从自身(比如说150,150)画一个圆弧到它自己(150,150),它渲染因为“哦,我已经在那里了,没有必要!”

我提供的解决scheme的好处是:

  1. 从一个圆圈直接转换到一个path很容易
  2. 两条弧线没有重叠(如果使用标记或图案等,这可能会导致问题)。 这是一个干净的连续线,虽然分成两部分。

如果他们只允许文本path接受形状,这些都不重要。 但是我认为他们正在避免这个解决scheme,因为圆形这样的形状元素在技术上并不具备“开始”的观点。

jsfiddle演示: http : //jsfiddle.net/crazytonyi/mNt2g/

更新:

如果您正在使用textPath引用的path,并且希望文本在弧的外边缘上呈现,则可以使用完全相同的方法,但将扫描标志从0更改为1,以便它将对象的外部path是表面而不是内部(把1,0想象成坐在中间的一个人,围绕自己画一个圆圈,而1,1是某人在半径距离的中间绕着中心行走,并在他们旁边拖动粉笔,如果这样的话任何帮助)。 这是上面的代码,但随着更改:

 <path d=" M cx cy m -r, 0 ar,r 0 1,1 (r * 2),0 ar,r 0 1,1 -(r * 2),0 " /> 

参考安东尼的解决scheme这里是一个函数来获取path:

 function circlePath(cx, cy, r){ return 'M '+cx+' '+cy+' m -'+r+', 0 a '+r+','+r+' 0 1,0 '+(r*2)+',0 a '+r+','+r+' 0 1,0 -'+(r*2)+',0'; } 

一个完全不同的方法:

除了用svg指定弧的path之外,还可以使用一个圆形元素并用伪代码指定一个stroke-dasharray:

 with $score between 0..1, and pi = 3.141592653589793238 $length = $score * 2 * pi * $r $max = 7 * $r (ie well above 2*pi*r) <circle r="$r" stroke-dasharray="$length $max" /> 

它的简单性是多弧path方法的主要优势(例如,当脚本只能插入一个值,并且完成任何弧长时)

弧线从最右端开始,可以使用旋转变换进行移动。

注意:Firefox有一个奇怪的错误,旋转超过90度或更多被忽略。 所以要从顶部开始弧,使用:

 <circle r="$r" transform="rotate(-89.9)" stroke-dasharray="$length $max" /> 

Adobe Illustrator使用像SVG这样的贝塞尔曲线,对于圆形它创build了四点。 你可以创build一个带有两个椭圆弧命令的圆圈,但是对于SVG中的一个圆圈,我会使用<circle /> 🙂

使用两个arc命令绘制一个完整的圆是一个好主意。

通常,我使用椭圆或圆形元素绘制一个完整的圆。

书面作为一个function,它看起来像这样:

 function getPath(cx,cy,r){ return "M" + cx + "," + cy + "m" + (-r) + ",0a" + r + "," + r + " 0 1,0 " + (r * 2) + ",0a" + r + "," + r + " 0 1,0 " + (-r * 2) + ",0"; } 

build立在安东尼和安东的答案上,我join了旋转生成的圆的能力,而不影响它的整体外观。 如果您使用animation的path并且需要控制它的开始位置,这非常有用。

 function(cx, cy, r, deg){ var theta = deg*Math.PI/180, dx = r*Math.cos(theta), dy = -r*Math.sin(theta); return "M "+cx+" "+cy+"m "+dx+","+dy+"a "+r+","+r+" 0 1,0 "+-2*dx+","+-2*dy+"a "+r+","+r+" 0 1,0 "+2*dx+","+2*dy; } 

另一种方法是使用两个立方贝塞尔曲线。 对于使用pocketSVG的iOS用户来说,这不能识别svg弧参数。

C x1 y1,x2 y2,xy(或c dx1 dy1,dx2 dy2,dx dy)

立方贝塞尔曲线

这里的最后一组坐标(x,y)是你想要结束的地方。 另外两个是控制点。 (x1,y1)是曲线起点的控制点,(x2,y2)是曲线终点。

 <path d="M25,0 C60,0, 60,50, 25,50 C-10,50, -10,0, 25,0" /> 

对于像我这样寻找椭圆属性来进行path转换的人:

 const ellipseAttrsToPath = (rx,cx,ry,cy) => `M${cx-rx},${cy}a${rx},${ry} 0 1,0 ${rx*2},0a${rx},${ry} 0 1,0 -${rx*2},0` 

我做了一个jsfiddle在这里做:

 function polarToCartesian(centerX, centerY, radius, angleInDegrees) { var angleInRadians = (angleInDegrees-90) * Math.PI / 180.0; return { x: centerX + (radius * Math.cos(angleInRadians)), y: centerY + (radius * Math.sin(angleInRadians)) }; } function describeArc(x, y, radius, startAngle, endAngle){ var start = polarToCartesian(x, y, radius, endAngle); var end = polarToCartesian(x, y, radius, startAngle); var largeArcFlag = endAngle - startAngle <= 180 ? "0" : "1"; var d = [ "M", start.x, start.y, "A", radius, radius, 0, largeArcFlag, 0, end.x, end.y ].join(" "); return d; } console.log(describeArc(255,255,220,134,136)) 

链接

所有你需要做的就是改变console.log的input,并在控制台中得到结果