Draw a hollow circle in SVG
我不确定如何在SVG中绘制空心圆。
我想要一个充满颜色的环形,然后有一个黑色的轮廓。
我考虑的方式是有两个圆,一个圆的半径小于另一个圆。 问题是,当我填充它们时,如何使较小的圆与它所在的位置具有相同的填充颜色?
只需使用
1 2 3 | <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> |
如果要两种颜色,也可以这样:
1 2 3 4 | <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> |
感谢Chasbeen,我弄清楚了如何在SVG中制作出真正的戒指/甜甜圈。请注意,外圈实际上不是封闭的,只有在使用笔触时才会明显。当您有许多同心环时,特别是在它们是交互式的时(例如,使用CSS悬停命令),该功能非常有用。
对于绘制命令...
1 2 3 4 5 6 7 | 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以模拟交互性。请注意,不利的一面是,在起点(顶部)缺少单个像素,只有在添加笔触时才存在。
编辑:
找到了这样的答案(更好的是,这个答案),它描述了如何获得空的内脏。
MDragon00的答案有效,但是内圈和外圈没有完全对齐(例如居中)。
我使用4个半圆弧(反向的2个外部弧形和2个内部的反向弧形)稍微修改了他的方法,以使对齐方式完全正确。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <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 --> |
这是经典的甜甜圈形状
我不确定您是否要尝试使用标准SVG或生成SVG的JavaScript来实现这一目标
可以通过在单个路径定义中包含相对的" moveto"命令来实现该目标。
然后单击交互式示例右侧的"甜甜圈孔"。
至少您可以看到制作红色甜甜圈的路径定义。
您可以按照SVG规范执行此操作,方法是使用包含两个组件和fill-rule =" evenodd"的路径。这两个分量是半圆弧,它们连接形成一个圆(在下面的" d"属性中,它们各自以" z"结尾)。内圆内的面积不算作形状的一部分,因此交互性很好。
为了稍微说明一下," 340 260"是外圆的顶部中间," 290 290"是外圆的半径(两倍)," 340 840"是外圆的底部中间," 340 492"是内圆的顶部中间," 58 58"是内圆的半径(两倍)," 340 608"是内圆的底部中间。
1 2 3 4 5 | <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)"> This will only display on the donut </path> </svg> |
这是一个创建贝塞尔曲线的例程,该弧形尽可能接近一个圆。一个完整的圆圈需要四个路径。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | 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]}); } |