使用SVG的弧形路径绘制圆形图

nop*_*ole 139 geometry svg vml drawing geometric-arc

以下SVG路径可以绘制一个圆的99.99%:(在http://jsfiddle.net/DFhUF/46/上尝试它,看看你是否看到4个弧或只有2个,但请注意,如果它是IE,它会被渲染在VML中,而不是SVG,但有类似的问题)

M 100 100 a 50 50 0 1 0 0.00001 0
Run Code Online (Sandbox Code Playgroud)

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

M 100 100 a 50 50 0 1 0 0.00000001 0    
Run Code Online (Sandbox Code Playgroud)

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

M 100 100 a 50 50 0 1 0 0 0 
Run Code Online (Sandbox Code Playgroud)

怎么能修好?原因是我使用一个函数绘制一个弧的百分比,如果我需要"特殊情况"一个99.9999%或100%的弧来使用圆函数,那就太傻了.

同样,使用RaphaelJS的jsfiddle上的测试用例位于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分数时,则使用弧函数.

Ant*_*ony 394

我知道游戏有点晚了,但我记得这个问题是从新的时候开始我有类似的困难,如果还有人在寻找一个问题,我会意外地找到"正确"的解决方案:

<path 
    d="
    M cx cy
    m -r, 0
    a r,r 0 1,0 (r * 2),0
    a r,r 0 1,0 -(r * 2),0
    "
/>
Run Code Online (Sandbox Code Playgroud)

换句话说,这个:

<circle cx="100" cy="100" r="75" />
Run Code Online (Sandbox Code Playgroud)

可以通过以下方式实现:

  <path 
        d="
        M 100, 100
        m -75, 0
        a 75,75 0 1,0 150,0
        a 75,75 0 1,0 -150,0
        "
  />
Run Code Online (Sandbox Code Playgroud)

诀窍是有两个弧,第二个是在第一个离开的地方拾取并使用负直径返回到原始弧起点.

它不能在一个圆弧中完成一个圆圈的原因(我只是在推测)是因为你会告诉它从它自己(比如150,150)到它自己(150,150)绘制一个圆弧,它会渲染它因为"哦,我已经在那里,没有必要!".

我提供的解决方案的好处是:

  1. 它很容易从圆圈直接转换为路径,并且
  2. 两条弧线没有重叠(如果使用标记或图案等,可能会导致问题).这是一条干净的连续线,虽然是两件式的.

如果他们只允许文本路径接受形状,这一切都不重要.但我认为他们正在避免这种解决方案,因为像圆圈这样的形状元素在技术上并没有"起点".

jsfiddle demo:http://jsfiddle.net/crazytonyi/mNt2g/

更新:

如果您正在使用路径作为textPath参考,并且您希望文本在弧的外边缘上渲染,则可以使用完全相同的方法,但将sweep-flag从0更改为1,以便它处理外部的路径作为表面而不是内部(想象1,0有人坐在中心并围绕自己画一个圆圈,而1,1当有人在半径距离的中心走动并在他们旁边拖动他们的粉笔时,如果有任何帮助的话).以下是上面的代码,但有更改:

<path 
    d="
    M cx cy
    m -r, 0
    a r,r 0 1,1 (r * 2),0
    a r,r 0 1,1 -(r * 2),0
    "
/>
Run Code Online (Sandbox Code Playgroud)

  • 我认为这里的问题不是"哦,我已经在那里,没有必要!",因为通过提供1作为大弧标志,你明确告诉引擎你希望它走得更远.真正的问题是,有无数多个圆圈通过你的观点完全限制.这就解释了为什么当你想要360*弧时,引擎不知道该怎么做.它不适用于359.999的原因是这是数值上不稳定的计算,虽然技术上只有一个圆圈与请求匹配,但它可能不是你想要的那个 (10认同)

Tod*_*ain 33

XAML的弧也一样.用a关闭99.99%的弧线,Z你就得到了一个圆圈!


Ant*_*ash 15

在参考Anthony的解决方案时,这是一个获取路径的函数:

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';
}
Run Code Online (Sandbox Code Playgroud)


mvd*_*vds 10

完全不同的方法:

您可以使用圆形元素并在伪代码中指定stroke-dasharray,而不是摆弄在svg中指定弧的路径:

with $score between 0..1, and pi = 3.141592653589793238

$length = $score * 2 * pi * $r
$max = 7 * $r  (i.e. well above 2*pi*r)

<circle r="$r" stroke-dasharray="$length $max" />
Run Code Online (Sandbox Code Playgroud)

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

弧从最右边的点开始,可以使用旋转变换进行移动.

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

<circle r="$r" transform="rotate(-89.9)" stroke-dasharray="$length $max" />
Run Code Online (Sandbox Code Playgroud)


yog*_*ogi 6

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

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 Z`
Run Code Online (Sandbox Code Playgroud)


jav*_*bat 6

我在这里做了一个 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))
Run Code Online (Sandbox Code Playgroud)

关联

您需要做的就是更改console.log的输入并在控制台中获取结果


Phr*_*ogz 5

Adobe Illustrator使用像SVG这样的贝塞尔曲线,并为圆形创建四个点。您可以使用两个椭圆弧命令创建一个圆...但是对于SVG中的一个圆,我将使用<circle />:)

  • @动静能量正确,需要两条弧线路径(或者一条弧线在大多数情况下都是丑陋的,然后使用closepath命令一直直线到最后)。 (2认同)

rfo*_*foo 5

基于 Anthony 和 Anton 的回答,我加入了旋转生成的圆而不影响其整体外观的能力。如果您使用动画路径并且需要控制它的开始位置,这将非常有用。

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;
}
Run Code Online (Sandbox Code Playgroud)