在SVG中画一个空心圆


75

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

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

我想到的方式是有两个圆,一个圆的半径小于另一个圆。问题是,当我填充它们时,如何使较小的圆与它所在的位置具有相同的填充颜色?

Answers:


109

只需使用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>


9
问题是它不允许我也保留黑色轮廓。我想要一个黑色轮廓的环形。
luketorjussen 2011年

2
@luketorjussen:对我来说,这只是一个黑色轮廓。如果你想有一个不同的填充颜色,只需要改变填充属性
风铃草

@rampiom:我想要一个给定颜色的戒指,都带有黑色轮廓
luketorjussen 2011年

您可以用不同的半径在两个笔画之间进行两个笔画,这样一个笔画就可以伸出来
Robert Longson

1
谢谢,这适用于绘制空心圆:-)我想将其扩展到绘制通过其他形状空心挖空的任何形状(例如,带有中间空心圆的正方形)-我在这里
对此

15

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

-->


13

感谢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答案(更好的是,这个答案),它描述了如何获得空的内脏。


1
这个答案很棒!如果您希望环的内部不对悬停事件做出响应,那么这非常重要!
Michael Scott Cuthbert

为了真正精确之后的第二mx值是1不是0: m 1, outerRadius-innerRadius
大卫Konkoly

2

您可以按照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>

1

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

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


谢谢,这有所帮助。准确地找出实际上是很痛苦的(并且外部笔触距离关闭大约1个单位,这在我的书中还可以),但是我想出了从中制作任意中心点和外,内半径的环的语法这
Jawad

-2

这是创建贝塞尔曲线的例程,该贝塞尔曲线的弧形与圆弧几乎一样。一个完整的圆圈需要四个路径。

 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解决方案
Philip
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.