【问题标题】:How do SVG/EPS (vectors) clip a path by another path?SVG/EPS(矢量)如何通过另一条路径剪辑路径?
【发布时间】:2020-08-24 06:55:35
【问题描述】:

我试图了解 SVG 程序(如浏览器)如何通过给定的路径绘制形状。我很难理解如何绘制路径以及如何剪辑形状的一部分。

例如,考虑字母Å 和带有顶环的A。 SVG 代码是这样的

<svg viewBox="0 0 1800 1800" xmlns="http://www.w3.org/2000/svg">
<path 
d="
M484 0l-42 137h-245l-47 -137h-147l237 664h161l234 -664h-151z
M426 822q0 -47 -24 -71.5t-80 -24.5q-104 0 -104 96q0 46 25.5 71t78.5 25q56 0 80 -25t24 -71z
M319 515h-1l-85 -264h169z
M374 822q0 51 -52 51q-50 0 -50 -51q0 -49 50 -49q52 0 52 49z
" />
</svg>

JSFIDDLE

  • 第一行:绘制A 的主体。
  • 第二行:绘制一个顶部圆。
  • 第三行:从第一行剪下一个三角形。
  • 第四行:从第二行剪下一个小圆圈。

我的问题是:SVG 程序如何理解通过第二行绘制形状,但从现有形状中剪切形状?

显然答案是:如果路径在另一个路径中,则它会剪切,否则它会绘制。

我认为这不是全部的原因有两个:

  1. 需要大量计算才能确定一条路径是否在另一条路径中。
  2. 线的顺序并不重要(剪切路径不一定在绘图路径之后)。

当然,这不仅限于 SVG,其他矢量格式(例如 EPS)也是如此。

为了增加务实的观点,请将问题阅读为:我们如何解析(在任何编程语言中)上面的d 元素以找出哪个路径正在绘制(黑色)和哪个正在剪切(白色) 在上述 SVG 中给出的四个路径中?

【问题讨论】:

    标签: svg vector postscript eps


    【解决方案1】:

    从广义上讲,您根本不解析路径。

    相反,您可以在当前分辨率下将每个路径“扫描”转换为一系列矩形。每个反应角可能只有一个像素高,并且在给定 y 值处可能有多个矩形。

    对要填充或描边的路径和要作为剪辑应用的路径执行此操作,然后与一系列矩形相交。显然,这是一项简单得多的任务。然后填充矩形。

    当然,这确实会产生仅在给定分辨率下正确的结果。改变分辨率,你会得到一系列不同的矩形。然而,它以相当快的速度产生正确的输出。将两条任意路径相交以生成新的任意路径显然是一项复杂得多的任务,而且为了绘制结果,我们不需要执行。

    【讨论】:

    • 扫描转换的想法非常有帮助,但我仍然没有得到顺序独立性。在给定的分辨率下,程序会找到第一条路径内的像素。然后,扫描转换第二个路径:如果像素在前一个路径内,它将删除像素,否则将添加它们。在这种情况下,路径的顺序应该很重要。
    • 是的,路径的顺序很重要。路径被渲染时有效的剪切路径剪切。如果您稍后更新剪切路径,它不会改变渲染路径。新剪辑仅适用于后续操作。这对于 EPS 来说是绝对正确的,我认为对于 SVG 也是如此。
    【解决方案2】:

    在接下来的示例中,我将使用您示例中字母 A 的路径。

    在第一个 svg 元素中,字母 A 是从右到左绘制的,而孔的绘制方向相反:你得到了“剪辑”。

    在第二个示例中,我反转了绘制孔的部分。现在这部分的绘制方向与字母 A 的主要部分相同。现在你不会得到“剪辑”

    在第三个示例中,我像以前一样使用反向路径,但我添加了fill-rule="evenodd" 现在,由于"fill-rule attribute is a presentation attribute defining the algorithm to use to determine the inside part of a shape",孔被剪裁了。

    svg{width:30%;border:solid}
    <svg viewBox="-40 -40 900 900" xmlns="http://www.w3.org/2000/svg">
    <path 
    d="
    M484 0l-42 137h-245l-47 -137h-147l237 664h161l234 -664h-151z
    M319 515h-1l-85 -264h169z
    " />
    </svg>
    <svg viewBox="-40 -40 900 900" xmlns="http://www.w3.org/2000/svg">
    <path 
    d="
    M484 0l-42 137h-245l-47 -137h-147l237 664h161l234 -664h-151z
    M319,515L402,251L233,251L318,515L319,515z
    " />
    </svg>
    
    <svg viewBox="-40 -40 900 900" xmlns="http://www.w3.org/2000/svg">
    <path fill-rule="evenodd"
    d="
    M484 0l-42 137h-245l-47 -137h-147l237 664h161l234 -664h-151z
    M319,515L402,251L233,251L318,515L319,515z
    " />
    </svg>

    【讨论】:

    • 我明白你关于方向影响的观点。但是,我没有得到绘制形状的通用算法。真的是方向决定的吗?那么,它的标准是什么?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-25
    • 2016-10-19
    • 1970-01-01
    • 1970-01-01
    • 2019-06-22
    • 2021-11-28
    相关资源
    最近更新 更多