【问题标题】:Cut out one SVG <path> out of another one从另一个 SVG <path> 中切出一个
【发布时间】:2011-04-03 09:57:46
【问题描述】:

我有几个 SVG 路径如下所示:

M204.21121687607624,196.94037184487675L329.92080751248244,195.46306542867487A130,130,0,0,0,244.46261863233696,77.83995929783192Z
M198.39145828733604,195.04941765207442L235.83285625620988,75.03597952801854A130,130,0,0,0,97.55860203112616,119.9640082076644Z

我现在想添加另一条路径,但不是将它添加到形状中,而是从以前的路径中删除它。我怎样才能做到这一点?

我在 SVG 文档中找不到任何相关信息 - 感谢您的帮助!

【问题讨论】:

标签: image vector svg


【解决方案1】:

要在Tobias Snoad's answer 上展开,使用移动 命令拿起笔并在相反方向(如Brian Hempel pointed out)绘制第二个形状,将删除原始路径中的该部分。这是由于fill-rule:evenodd(默认),如this answer 中所述。

这是一个示例,它会绘制一个 10x10 的框,然后在其中反转一个 6x6 的框:

<svg xmlns="http://wwww3org/2000/svg" height="200" viewBox="0,0,10,10">
  <path d="M 0,0 h 10 v 10 h -10 z
           M 2,2 v  6 h  6 v  -6 z" /> 
</svg>

这将产生下图中的第二个框,每个点都标有编号和箭头,以便您查看方向:

这是一个正在运行的演示是 Stack Snippets

svg path.shape {
  fill: green;
  stroke: #1b1b1b;
  stroke-width: .5px;
}
svg path.arrow {
  fill: yellow;
  stroke: black;
  stroke-width: .1px;
}
svg text {
  font-size: .8px;
  font-family: monospace;
  stroke: navy;
  stroke-width: .1px;
  text-anchor: middle;
  alignment-baseline: middle;
}
svg circle {
  r: .5;
  stroke: navy;
  stroke-width: .1px;
  fill: yellow;
}
<svg xmlns="http://wwww3org/2000/svg" height="200" viewBox="-2,-2,14,14">

  <defs>
    <marker id='arrow' orient="auto"  
          refX='-.9' refY='1'
          markerWidth='2' markerHeight='2' >
      <!-- triangle pointing right (+x) -->
      <path d='M 0,0 V 2 L 1,1 Z' class="arrow"/>
    </marker>
  </defs>    

  <path d="M 0,0 h 10 v 10 h -10 z
           M 2,2 h  6 v  6 h  -6 z"  
        marker-mid='url(#arrow)' class="shape" />
                             
    <circle cx="0" cy="0" />                  
    <text    x="0"  y="0" > 1</text>    
    <circle cx="10" cy="0" />                  
    <text    x="10"  y="0" > 2</text>  
    <circle cx="10" cy="10" />                  
    <text    x="10"  y="10" > 3</text>  
    <circle cx="0" cy="10" />                  
    <text    x="0"  y="10" > 4</text>  
    <circle cx="2" cy="2" />                  
    <text    x="2"  y="2" > 5</text>  
    <circle cx="8" cy="2" />                  
    <text    x="8"  y="2" > 6</text>  
    <circle cx="8" cy="8" />                  
    <text    x="8"  y="8" > 7</text>  
    <circle cx="2" cy="8" />                  
    <text    x="2"  y="8" > 8</text>  
</svg>

<svg xmlns="http://wwww3org/2000/svg" height="200" viewBox="-2,-2,14,14">
 
  <path d="M 0,0 h 10 v 10 h -10 z
           M 2,2 v  6 h  6 v  -6 z" 
        marker-mid='url(#arrow)' class="shape" /> 
   
    <circle cx="0" cy="0" />                  
    <text    x="0"  y="0" > 1</text>    
    <circle cx="10" cy="0" />                  
    <text    x="10"  y="0" > 2</text>  
    <circle cx="10" cy="10" />                  
    <text    x="10"  y="10" > 3</text>  
    <circle cx="0" cy="10" />                  
    <text    x="0"  y="10" > 4</text>  
    <circle cx="2" cy="2" />                  
    <text    x="2"  y="2" > 5</text>  
    <circle cx="2" cy="8" />                  
    <text    x="2"  y="8" > 6</text>      
    <circle cx="8" cy="8" />                  
    <text    x="8"  y="8" > 7</text>  
    <circle cx="8" cy="2" />                  
    <text    x="8"  y="2" > 8</text>  
</svg>

SVG 路径命令刷新器

两种变体

  • M 100,150 大写 (Absolute) - 移动到精确坐标 100,150 (x,y)
  • m 100,150 小写(相对) - 将笔 100 向下移动,150 向右移动

直接命令

  • M <i>x,y</i> - 拿起笔,M点到为止x,y
  • L <i>x,y</i> - 画一条直线 Line 到点 x,y
  • H <i>x</i> - 在 x 的右侧水平方向画一条 H线
  • V <i>y</i> - 以 y 垂直向下画一条线 V
  • Z|z - 通过画一条直线回到起点(最后一个 M 位置)来关闭路径
    注意Z 完全可选 - 它只是一个返回起点的快捷方式

曲线命令

  • C <i>cX1,cY1 cX2,cY2 eX,eY</i> - 根据两个贝塞尔控制点绘制贝塞尔C曲线,并在坐标处结束eX,eY
  • S <i>cX2,cY2 eX,eY</i> - 根据之前的 S|C 控制点和 One 指定的贝塞尔控制点绘制 S 简化曲线,并在坐标 eX,eY
  • Q <i>cX2,cY2 eX,eY</i> - 根据 One 贝塞尔控制点绘制 Qudratic 曲线,并在坐标 eX,eY 处结束
  • T <i>eX,eY</i> - 根据之前的贝塞尔控制点绘制T末端二次曲线,并在坐标处结束eX,eY
  • A <i>rX,rY rotation, arc, sweep, eX,eY</i> - 为具有指定宽度 rX 和高度 rY 的椭圆绘制椭圆 Arc。为 arcsweep 定义度数和方向为 0|1 的 rotation 并在坐标 处结束eX,eY

提示:在大多数情况下,您可以简化任何自动生成的路径点的精度,而不会牺牲任何人的可识别性,即使是在大量缩放时也是如此。您可以使用正则表达式 find ([0-9]*)(\.[0-9]*) and replace with $1 删除任何尾随小数。您还可以使用find \s*([a-zA-z])\s* and replace with \n$1 格式化每个命令在其自己的行中。

延伸阅读:

【讨论】:

【解决方案2】:

你可以用一条路径做到这一点:

M 0,0 l 0,10 10,0 0,-10 -10,0 z m 2,2 l 6,0 0,6 -6,0 0,-6 z

这将绘制一个 10x10 的正方形,中间有一个 6x6 的孔

【讨论】:

  • 只要确保切口的顺时针/逆时针顺序正确。如果您的切口没有被切掉,请颠倒点的顺序。
  • @BrianHempel,除非fill-rule 属性是evenodd
【解决方案3】:

SVG 不支持路径上的布尔运算。但是,您可以使用一个路径作为clipping path,这将为您提供所需的效果。

【讨论】:

  • Clip-Path 只允许您将一个形状绑定到另一个形状中,定义一个非矩形容器。但我不相信你可以用剪辑路径剪掉中间,这样做会像整个形状的容器一样,你*只会得到中间。您可以添加mask,但也有一些限制。
【解决方案4】:

矢量图形编辑器通常会为您提供此功能。在 Inkscape 中选择两条路径,然后在“路径”菜单上选择要执行的操作。 Illustrator 也具有相同的功能。

【讨论】:

    猜你喜欢
    • 2013-06-28
    • 2014-04-30
    • 2022-01-15
    • 1970-01-01
    • 2021-08-03
    • 2020-10-25
    • 2017-05-03
    • 1970-01-01
    • 2012-04-24
    相关资源
    最近更新 更多