【问题标题】:Draw a hollow circle in SVG在 SVG 中画一个空心圆
【发布时间】:2011-11-19 11:19:37
【问题描述】:

我不确定如何在 SVG 中绘制一个空心圆。

我想要一个用颜色填充然后有黑色轮廓的环形。

我想这样做的方式是有 2 个圆,一个比另一个半径小。问题是当我填充它们时,如何使较小的圆圈采用与其所在位置相同的填充颜色?

【问题讨论】:

    标签: svg


    【解决方案1】:

    只需使用fill="none",然后只会绘制stroke(轮廓)。

    <svg xmlns="http://www.w3.org/2000/svg" version="1.1">
       <circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="none" />
    </svg> 

    如果你想要两种颜色,也可以这样:

    <svg xmlns="http://www.w3.org/2000/svg" version="1.1">
       <circle cx="100" cy="50" r="40" stroke="black" stroke-width="3" fill="none" />
       <circle cx="100" cy="50" r="39" stroke="red" stroke-width="2" fill="none" />
    </svg>

    【讨论】:

    • 这个问题是它不允许我也保留黑色轮廓。我想要一个带有黑色轮廓的环形。
    • @luketorjussen:对我来说,这只是一个黑色轮廓。如果您想要不同的填充颜色,只需更改填充属性
    • @rampiom:我想要一个给定颜色的戒指,所有的都是黑色的轮廓
    • 你可以用不同的半径在另一个上面做两个笔画,这样一个会突出
    • 谢谢,这适用于绘制空心圆 :-) 我想将其扩展到绘制任何被不同形状挖空的形状(例如,中间圆空心的正方形) - 我已经发布这个here的另一个问题@
    【解决方案2】:

    MDragon00 的回答有效,但内圈和外圈没有完全对齐(例如居中)。

    我稍微修改了他的方法,使用 4 个半圆弧(2 个外部和 2 个内部反向)来完全正确地对齐。

    <svg width="100" height="100">
      <path d="M 50 10 A 40 40 0 1 0 50 90 A 40 40 0 1 0 50 10 Z M 50 30 A 20 20 0 1 1 50 70 A 20 20 0 1 1 50 30 Z" fill="#0000dd" stroke="#00aaff" stroke-width="3" />
    </svg>
    
    <!--
    
    Using this path definition as d:
    
    M centerX (centerY-outerRadius)
    A outerRadius outerRadius 0 1 0 centerX (centerY+outerRadius)
    A outerRadius outerRadius 0 1 0 centerX (centerY-outerRadius)
    Z
    M centerX (centerY-innerRadius)
    A innerRadius innerRadius 0 1 1 centerX (centerY+innerRadius)
    A innerRadius innerRadius 0 1 1 centerX (centerY-innerRadius)
    Z
    
    -->

    【讨论】:

      【解决方案3】:

      感谢 Chasbeen,我想出了如何在 SVG 中制作真正的戒指/甜甜圈。请注意,外圈实际上并没有闭合,这仅在您使用笔画时才明显。当您有许多同心环时非常有用,尤其是当它们是交互式的(例如,使用 CSS 悬停命令)时。

      对于绘图命令...

      M cx, cy // Move to center of ring
      m 0, -outerRadius // Move to top of ring
      a outerRadius, outerRadius, 0, 1, 0, 1, 0 // Draw outer arc, but don't close it
      Z // default fill-rule:even-odd will help create the empty innards
      m 0 outerRadius-innerRadius // Move to top point of inner radius
      a innerRadius, innerRadius, 0, 1, 1, -1, 0 // Draw inner arc, but don't close it
      Z // Close the inner ring. Actually will still work without, but inner ring will have one unit missing in stroke       
      

      JSFiddle - 包含几个环和 CSS 来模拟交互性。请注意,起点(顶部)缺少一个像素,只有在添加笔画时才会出现。

      编辑: 找到了这个SO answer(更好的是this answer),它描述了如何获得一般的空内脏

      【讨论】:

      • 这个答案太棒了!如果您希望环的内部不响应悬停事件,那么这一点非常重要!
      • 准确地说第二个m x 值是1 而不是0:m 1, outerRadius-innerRadius
      【解决方案4】:

      您可以按照 SVG 规范通过使用包含两个组件和 fill-rule="evenodd" 的路径来执行此操作。这两个组件是连接形成一个圆的半圆弧(在下面的“d”属性中,它们每个都以“z”结尾)。内圈内的区域不计入形状的一部分,因此交互性很好。

      稍微解码下面,“340 260”是外圆的顶部中间,“290 290”是外圆的半径(两倍),“340 840”是底部中间外圆,“340 492”是内圆的顶部中间,“58 58”是内圆的半径(两倍),“340 608”是内圆的底部中间。

      <svg viewBox="0 0 1000 1000" xmlns="http://www.w3.org/2000/svg">
          <path fill-rule="evenodd" d="M340 260A290 290 0 0 1 340 840A290 290 0 0 1 340 260zM340 492A58 58 0 0 1 340 608A58 58 0 0 1 340 492z" stroke-width="4" stroke="rgb(0,0,0)" fill="rgb(0,0,255)">
              <title>This will only display on the donut</title>
          </path>
      </svg>
      

      【讨论】:

        【解决方案5】:

        这是经典的甜甜圈形状 我不确定您是否正在尝试使用标准 SVG 或生成 SVG 的 JavaScript 来实现这一点 该目标可以通过在单个路径定义中包含相对“moveto”命令来实现

        然后单击交互式示例右侧的“甜甜圈洞”。 至少您可以看到制作红色甜甜圈的路径定义。

        【讨论】:

        • 谢谢,这有帮助。准确地弄清楚实际上是一件痛苦的事(外笔画距离闭合大约 1 个单位,这在我的书中是可以的),但我想出了制作任意中心点和外半径和内半径的环的语法这个
        【解决方案6】:

        这是一个创建贝塞尔曲线的例程,该曲线尽可能接近圆形。一条完整的圆圈需要其中四个。

         BezierCurve BezierArc(double ox, double oy, double r, double thetaa, double thetab)
            {
                double theta;
                double cpx[4];
                double cpy[4];
                int i;
                int sign = 1;
        
                while (thetaa > thetab)
                    thetab += 2 * Pi;
                theta = thetab - thetaa;
                if (theta > Pi)
                {
                    theta = 2 * Pi - theta;
                    sign = -1;
                }
                cpx[0] = 1;
                cpy[0] = 0;
                cpx[1] = 1;
                cpy[1] = 4.0 / 3.0 * tan(theta / 4);
                cpx[2] = cos(theta) + cpy[1] * sin(theta);
                cpy[2] = sin(theta) - cpy[1] * cos(theta);
                cpx[3] = cos(theta);
                cpy[3] = sin(theta);
                cpy[1] *= sign;
                cpy[2] *= sign;
                cpy[3] *= sign;
        
                for (i = 0; i < 4; i++)
                {
                    double xp = cpx[i] * cos(thetaa) + cpy[i] * -sin(thetaa);
                    double yp = cpx[i] * sin(thetaa) + cpy[i] * cos(thetaa);
                    cpx[i] = xp;
                    cpy[i] = yp;
                    cpx[i] *= r;
                    cpy[i] *= r;
                    cpx[i] += ox;
                    cpy[i] += oy;
                }
        
                return BezierCurve({cpx[0], cpy[0]},{cpx[1], cpy[1]}, {cpx[2], cpy[2]}, {cpx[3], cpy[3]});
            }
        

        【讨论】:

        • 获得与其他答案相同的结果的函数相当长。加上 OP 想要一个 SVG 解决方案
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-21
        • 2017-01-16
        • 1970-01-01
        相关资源
        最近更新 更多