代码之家  ›  专栏  ›  技术社区  ›  user4891

我怎样才能把一个形状切成另一个形状呢?

svg
  •  28
  • user4891  · 技术社区  · 16 年前

    在SVG中有没有一种方法可以将一个形状从另一个形状中剪切出来?例如,我有一个矩形和一个椭圆,我想做一个中间有一个透明孔的矩形。我可以想象它会像这样:

    <set operation="difference" fill="black">
        <rect x="10" y="10" width="50" height="50/>
        <ellipse cx="35" cy="35" rx=10 ry=10/>
    </set>
    

    我能找到的最接近的东西是剪辑,它将给我两个形状的交集。在我的例子中,这只会导致洞是实心的,而直肠的其余部分是透明的。

    我浏览了Inkscape,在路径菜单中有一个不同的选项,但是这会将形状转换为路径,然后创建一个新的路径。形状的标识丢失,因此没有简单的方法,例如,进入SVG文件并更改椭圆的半径。

    我能怎么做吗?

    4 回复  |  直到 9 年前
        2
  •  35
  •   Community Mohan Dere    9 年前

    必须使用路径元素来切割孔。

    请参阅SVG规范中的示例(您可以单击此链接或以下图像查看实际SVG文件)。

    <g fill rule=“evenodd”fill=“red”stroke=“black”stroke width=“3”>
    <path d=“M 250,75 L 323031 131161 369161 177301 Z”/>
    
    <path d=“M 600,81 A 107107 0 0,1 600295 A 107107 0 0,1 600,81 Z
    M 600139 A 49,49 0 0,1 600237 A 49,49 0 0,1 600139 Z“/>
    
    <path d=“M 950,81 A 107107 0 0,1 950295 A 107107 0 0,1 950,81 Z
    M 950139 A 49,49 0 0,0 950237 A 49,49 0 0,0 950139 Z“/>
    lg/g/gt;
    < /代码> 
    
    

    对于您的案例:

    <path d=“m110h50v50h-50z m23 35a14 10 0 1 0 0.0001 z”
    stroke=“blue”stroke width=“2”fill=“red”fill rule=“evenodd”/>gt;
    < /代码> 
    
    

    m110h50v50h-50zwill draw a rect.

    M25 35A10 10 0 1 1 0 0.0001 Zwill draw a椭圆。

    fill rule=“evenodd”will make the hole.


    关键是在不同的方向(顺时针和逆时针)绘制外部形状和内部形状(孔)。

    • 顺时针绘制外部形状,逆时针绘制内部(孔)形状。
    • 或者相反,逆时针绘制外部形状(孔),顺时针绘制内部形状。
    • concat外部形状和内部形状(孔)的路径数据。

    您可以通过concat more hole path data切割更多的孔。

    这张图片解释了如何切割一个孔:

    见W3C文件: svg arc命令 和 svg fill rule property。

    :(您可以单击此链接或下图查看真正的SVG文件)

    svg hole example

    <g fill-rule="evenodd" fill="red" stroke="black" stroke-width="3">
        <path d="M 250,75 L 323,301 131,161 369,161 177,301 z"/>
    
        <path d="M 600,81 A 107,107 0 0,1 600,295 A 107,107 0 0,1 600,81 z
                 M 600,139 A 49,49 0 0,1 600,237 A 49,49 0 0,1 600,139 z"/>
    
        <path d="M 950,81 A 107,107 0 0,1 950,295 A 107,107 0 0,1 950,81 z
                 M 950,139 A 49,49 0 0,0 950,237 A 49,49 0 0,0 950,139 z"/>
    </g>
    

    对于你的情况:

    <path d="M10 10h50v50h-50z M23 35a14 10 0 1 1 0 0.0001 z"
        stroke="blue" stroke-width="2" fill="red" fill-rule="evenodd" />
    

    M10 10h50v50h-50z将绘制矩形。

    M25 35a10 10 0 1 1 0 0.0001 z将绘制椭圆。

    fill-rule="evenodd"会打洞的。


    关键是在不同的方向(顺时针和逆时针)绘制外部形状和内部形状(孔)。

    • 顺时针绘制外部形状,逆时针绘制内部(孔)形状。
    • 或者相反,逆时针绘制外部形状(孔),顺时针绘制内部形状。
    • 确定内外形(孔)的路径数据。

    您可以通过concat more hole path数据来切割更多的孔。

    此图说明了如何切割孔:

    This image explain how to cut a hole

    参见W3C文档: SVG Arc Commands 和 SVG fill-rule Property.

        3
  •  2
  •   Erik Dahlström    16 年前

    你需要使用 <path> 如果你想用 fill-rule . 但是可以改变一个圆的半径,这个圆是 <路径& GT; 你只需要掌握 arc path command .

        4
  •  -1
  •   Kornel Kisielewicz    16 年前

    不幸的是,似乎没有办法做到这一点。SVG 1.0和SVG 1.1都不支持布尔形状操作,因为其他原因支持剪切。你能得到的最接近的是试图得到一个“倒置”的形状来做剪辑。