在SVG中从另一个圆中减去一个圆

     2023-03-23     206

关键词:

【中文标题】在SVG中从另一个圆中减去一个圆【英文标题】:Subtract one circle from another in SVG 【发布时间】:2014-04-30 01:04:59 【问题描述】:

我正在尝试找到一种方法,在 SVG 中从另一个形状中减去一个形状,在中间创建一个洞或从它的侧面咬出一个洞。有点像剪切路径,但不是显示交叉点,我想显示交叉点外的一个部分。 One solution 涉及使用 Adob​​e 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】:

面具就是你想要的。要创建&lt;mask&gt;,请将您想要保留的内容设为白色。你想要隐形的东西会变黑。中间的颜色会导致半透明。

因此生成的 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 中工作。 有什么办法可以改变颜色吗?比如如果我想让黑色圆圈部分是白色的,而中间的圆圈是半透明的呢? 当然可以。只需设置填充:&lt;circle id="donut" r="100" cx="100" cy="100" mask="url(#hole)" fill="white" /&gt; @Shivam 是的。但是过滤器是在遮罩之前应用的,所以您只需将其包装在一个组中,然后将过滤器应用于该组即可。 jsfiddle.net/86jnkr3L【参考方案3】:

两个答案建议 (1) 使用 或 (2) 使用“fill-rule=evenodd”属性从形状 A 中减去形状 B em> (A ∖ B).

两个建议的答案都解决了问题的“中间的洞”(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>

【讨论】:

如何在 C#2.0 中从另一个通用列表中减去一个通用列表

】如何在C#2.0中从另一个通用列表中减去一个通用列表【英文标题】:HowtosubtractonegenericlistfromanotherinC#2.0【发布时间】:2010-02-1514:52:35【问题描述】:首先,很可能是我以错误的方式处理我的问题,在这种情况下,我很乐意接受... 查看详情

在 Swift 中从另一个 ViewController 访问变量

】在Swift中从另一个ViewController访问变量【英文标题】:AccessingvariablesfromanotherViewControllerinSwift【发布时间】:2014-06-0601:23:22【问题描述】:我有以下ViewController:classPageContentViewController:UIViewControllervarpageIndex:Int如何从另一个ViewCon... 查看详情

在 SQL 中从另一个表更新一个表的最佳方法是啥?

】在SQL中从另一个表更新一个表的最佳方法是啥?【英文标题】:WhatisthebestwaytoupdateaonetablefromanotherinSQL?在SQL中从另一个表更新一个表的最佳方法是什么?【发布时间】:2016-12-2116:00:45【问题描述】:我有2个表,第一个是产品页... 查看详情

如何在 Nuxt 中从另一个访问一个 Vuex 状态?

】如何在Nuxt中从另一个访问一个Vuex状态?【英文标题】:HowtoaccessoneVuexstatefromanotherinNuxt?【发布时间】:2020-10-2613:43:34【问题描述】:我在Nuxtstore目录中有两个Vuex存储。即使通过routeState,我也无法从另一家商店访问一家商店的... 查看详情

在java中从另一个调用一个构造函数[重复]

】在java中从另一个调用一个构造函数[重复]【英文标题】:calloneconstructorfromanotherinjava[duplicate]【发布时间】:2011-01-2308:35:47【问题描述】:这是面试时被问到的问题。如果一个类在java中有多个构造函数,我们可以从另一个构造... 查看详情

在php中从另一个数组创建一个数组[关闭]

】在php中从另一个数组创建一个数组[关闭]【英文标题】:Creatingonearrayfromanotherarrayinphp[closed]【发布时间】:2016-05-3003:06:35【问题描述】:我有一个看起来像这样的数组。这是一个二维数组。$MainArray=Array([0]=>Array([Job_Name]=>WXY... 查看详情

如何在 C# 中从另一个列表中删除列表

】如何在C#中从另一个列表中删除列表【英文标题】:HowToRemoveListFromAnotherListInC#【发布时间】:2021-06-1500:24:55【问题描述】:这里我有两个列表varuserListFromFriendTable=mainService.GetUserFromFriend(ChattingUserName);和vargetAllUserFromMessageUserTable... 查看详情

java示例代码_在android中从另一个应用调用或调用一个应用

java示例代码_在android中从另一个应用调用或调用一个应用 查看详情

如何在 Java 中从另一个构造函数调用一个构造函数?

】如何在Java中从另一个构造函数调用一个构造函数?【英文标题】:HowdoIcalloneconstructorfromanotherinJava?【发布时间】:2010-09-2201:26:51【问题描述】:是否可以从另一个(在同一个类中,而不是从子类中)调用构造函数?如果是怎... 查看详情

如何在 React 中从另一个组件设置一个组件的状态

】如何在React中从另一个组件设置一个组件的状态【英文标题】:Howtosetonecomponent\'sstatefromanothercomponentinReact【发布时间】:2020-10-0312:44:09【问题描述】:假设我有以下名为Home的组件:this.state=posts:[]componentDidMount()...dataisfetchedfroma... 查看详情

java示例代码_在java中从另一个页面调用函数

java示例代码_在java中从另一个页面调用函数 查看详情

如何在颤动中从另一个屏幕进行更改

】如何在颤动中从另一个屏幕进行更改【英文标题】:howtomakechangesfromanotherscreeninflutter【发布时间】:2020-09-0817:51:13【问题描述】:我是Flutter的新手,我在项目的逻辑部分需要帮助,所以如果这个问题不属于SOF,请告诉我。所... 查看详情

如何在 Reactjs 中从另一个组件触发状态

】如何在Reactjs中从另一个组件触发状态【英文标题】:HowtotriggerastatefromanothercomponentInReactjs【发布时间】:2021-03-3018:56:36【问题描述】:你好,我需要帮助。我有一个进度条组件和一个在其中使用进度条的组件。以及另一个应该... 查看详情

在一个查询中从另一个类中检索数据

】在一个查询中从另一个类中检索数据【英文标题】:Retrievingdatafromanotherclassinonequery【发布时间】:2015-03-2400:30:59【问题描述】:我构建了一个使用Parse的应用程序。我的应用程序允许用户注册、登录然后发布到解析云数据库。... 查看详情

熊猫在一个系列中从另一个系列中找到超级字符串

】熊猫在一个系列中从另一个系列中找到超级字符串【英文标题】:PandasfindsuperstringinoneSeriesfromanotherSeries【发布时间】:2018-12-0715:57:40【问题描述】:这不一定需要在pandas中完成,但如果可以在pandas中完成就更好了。假设我有... 查看详情

在 AngularJS 中从另一个模块导入组件的最佳方法是啥?

】在AngularJS中从另一个模块导入组件的最佳方法是啥?【英文标题】:Whatisthebestwaytoimportacomponentfromanothermodule,inAngularJS?在AngularJS中从另一个模块导入组件的最佳方法是什么?【发布时间】:2020-06-0301:19:52【问题描述】:我的Angul... 查看详情

在 Oracle 中从另一个存储过程调用一个存储过程

】在Oracle中从另一个存储过程调用一个存储过程【英文标题】:CallingonestoredprocedurefromanotherinOracle【发布时间】:2012-04-1705:04:54【问题描述】:在Oracle数据库中,假设有两个存储过程并且存储过程sp1正在调用另一个存储过程sp2问... 查看详情

在 Access 中从另一个表的数据创建一个表

】在Access中从另一个表的数据创建一个表【英文标题】:CreatingonetablefromdataofanothertableinAccess【发布时间】:2017-12-3002:05:04【问题描述】:这个问题是关于MSAccess。我想要做的是我在Access中有一个表,并且想使用第一个表中的数据... 查看详情