在SVG中从另一个圆中减去一个圆
Posted
技术标签:
【中文标题】在SVG中从另一个圆中减去一个圆【英文标题】:Subtract one circle from another in SVG 【发布时间】:2014-04-30 01:04:59 【问题描述】:我正在尝试找到一种方法,在 SVG 中从另一个形状中减去一个形状,在中间创建一个洞或从它的侧面咬出一个洞。有点像剪切路径,但不是显示交叉点,我想显示交叉点外的一个部分。 One solution 涉及使用 Adobe Flex,但我不知道如何正确实施。我知道在 Inkscape 中有一种方法可以使用布尔路径操作来执行此操作,但我想保持圆形元素的原样,而不是将它们更改为路径元素。
<defs>
<subtractPath id="hole">
<circle r="50" cx="100" cy="100" />
</subtractPath>
</defs>
<circle id="donut" r="100" cx="100" cy="100" subtract-path="url(#hole)" />
【问题讨论】:
【参考方案1】:诀窍是使用fill-rule 来控制剪辑路径的显示。一个(方形)甜甜圈的例子是
<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg"
>
<defs>
</defs>
<g transform="translate(50, 50)">
<path d="M 0 0 L 0 200 L 200 200 L 200 0 z
M 50 50 L 50 150 L 150 150 L 150 50 z" fill-rule="evenodd"/>
</g>
</svg>
这使用形状的填充规则属性来删除内部正方形 - 您可以调整它以使用贝塞尔路径来完成,以根据需要创建一个圆。
创建基本剪辑路径后,您可以从中创建剪辑路径 - 有关剪辑路径的信息,请参阅 this MDN entry。
【讨论】:
【参考方案2】:面具就是你想要的。要创建<mask>
,请将您想要保留的内容设为白色。你想要隐形的东西会变黑。中间的颜色会导致半透明。
因此生成的 SVG 类似于您的伪标记,如下所示:
<div style="background: #ddf">
<svg >
<defs>
<mask id="hole">
<rect fill="white"/>
<circle r="50" cx="100" cy="100" fill="black"/>
</mask>
</defs>
<circle id="donut" r="100" cx="100" cy="100" mask="url(#hole)" />
</svg>
</div>
我们用一个白色矩形填充蒙版,然后在我们想要的孔位置放置一个黑色圆圈。
【讨论】:
是的,这就是我要找的。我没有想过在面具中使用两个形状。它可以在我的浏览器中运行,但对于我的一生,我无法让它在 Inkscape 中运行。它所做的只是显示大圆圈。会不会是 Inkscape 的错误? 回答我自己的问题,只要一个组包含掩码中的元素,它就可以在 Inkscape 中工作。 有什么办法可以改变颜色吗?比如如果我想让黑色圆圈部分是白色的,而中间的圆圈是半透明的呢? 当然可以。只需设置填充:<circle id="donut" r="100" cx="100" cy="100" mask="url(#hole)" fill="white" />
@Shivam 是的。但是过滤器是在遮罩之前应用的,所以您只需将其包装在一个组中,然后将过滤器应用于该组即可。 jsfiddle.net/86jnkr3L【参考方案3】:
两个答案建议 (1) 使用
两个建议的答案都解决了问题的“中间的洞”(B ⊆ A) 部分,但只有 mask 方法是解决“咬伤”的合理解决方案出边”部分(B ⊈ A)。使用 evenodd 填充规则意味着两个形状被平等对待,因此第二个形状不与第一个相交的部分将成为结果的一部分。为了咬出某种形状,“咬”形状必须与被咬形状共享部分边界。这在实践中可能很难实现。
一个例子:为了从另一个圆中减去一个圆,您必须创建一个“咬合”形状,它是两个圆的交点。
掩码方法更为普遍。
【讨论】:
这并不能真正回答原始问题。我害怕作为一个真正需要的答案。如果删除其他答案中的一个或两个,则很难理解您的意思。 @RobertLongson:感谢您指出这一点。我不知道可以删除答案。所以我想我的将被删除而无需任何进一步的操作。 为什么不把它转换成可以回答问题的东西呢?【参考方案4】:|*|蒙版:用于减去对象:
|=> fill="white" => 要显示的块 |=> fill="black" => 要删除的块
|=> fill="white" => 将显示块也放在掩码标签内并填充白色 |=> fill="black" => 将 Remove Block 放在 mask 标签内并填充黑色
|::|使用掩码从大矩形中删除中心小矩形的示例
<rect x="20" y="20" mask="url(#rmvRct)"/>
<mask id="rmvRct">
<rect x="20" y="20" fill="white"/>
<rect x="40" y="40" fill="black"/>
</mask>
|::|使用掩码从大圆中删除中心小圆的示例:
<circle cx="50" cy="50" r="45" mask="url(#rmvCir)"/>
<mask id="rmvCir">
<circle cx="50" cy="50" r="45" fill="white"/>
<circle cx="50" cy="50" r="25" fill="black"/>
</mask>
【讨论】:
以上是关于在SVG中从另一个圆中减去一个圆的主要内容,如果未能解决你的问题,请参考以下文章
2015 NCPC Problem G-Goblin Garden Guards