【问题标题】:SVG reduced path with fill pattern带有填充图案的 SVG 缩减路径
【发布时间】:2019-10-01 21:55:00
【问题描述】:

我尝试绘制一个带有必须减少的路径的形状,就像在这个解决方案Find Parallel or Offset SVG path 中一样 我使用过滤器“侵蚀”,但使用图案它不起作用:图案变形了。

有没有办法在没有 bezier.js 解决方案的情况下使用纯 SVG/CSS 来做到这一点?

这是我的问题的一个示例 我想要右边的形状和左边的图案。

<!DOCTYPE html>
<html>
    <body>
        <svg>
            <defs>
                <pattern id="circ" x="0" y="0" width="30" height="30" patternUnits="userSpaceOnUse">
                    <rect fill="blue" width="100%" height="100%" />
                    <circle cx="10" cy="10" r="10" fill="green" />
                </pattern>
                <filter id="erode">
                    <feMorphology in="SourceGraphic" operator="erode" radius="10"/>
                </filter>
                <path id="thing" d="M 0,0 H 50 A 35,35 0 1 0 100,50 V 75 C 50,125 0,85 0,85 Z" />
            </defs>
            <use href="#thing" fill="url(#circ)" width="400" height="400" filter="#erode"/>
            <use x="100" href="#thing" filter="url(#erode)" fill="url(#circ)" width="400" height="400" />
        </svg>
    </body>
</html>

【问题讨论】:

  • 这取决于您使用的模式。对于许多模式,仍然可以单独使用过滤器并使用更多原语。请将您要执行此操作的 SVG 代码发布到。
  • 我用 sn-p 编辑了我的问题来说明我的问题。谢谢@MichaelMullany
  • 我觉得是这个滤镜的一个特点(光栅化缩减)
  • 想出了如何解决浏览器错误...发布了答案

标签: svg svg-filters


【解决方案1】:

是的。你可以使用面具。

svg {
  width: 300px;
}

.purple {
  fill: rebeccapurple;
}

.reduce-me {
  mask: url(#reducer);
}

#reduce-amount {
  stroke-width: 5px;
}
<svg viewBox="0 0 100 100">
  <path class="purple"
        d="M 50,10 Q 100,10, 50,50 Q 0,90, 50,90 
           Q 100,90, 50,50 Q 0,10, 50,10 Z"/>
</svg>


<svg viewBox="0 0 100 100">
  <defs>
    <!-- the shared path that is used by both the purple path and the mask -->
    <path id="shared-path"
          id="p" d="M 50,10 Q 100,10, 50,50 Q 0,90, 50,90
                    Q 100,90, 50,50 Q 0,10, 50,10 Z" />

    <!-- a mask that shrinks the shape by half the stroke-width -->
    <mask id="reducer">
      <use id="reduce-amount" xlink:href="#shared-path"
           fill="white" stroke="black"/>
    </mask>
  </defs>

  <!-- the shape that gets reduced -->
  <use class="purple reduce-me" xlink:href="#shared-path"/>
</svg>

这是如何工作的

如果我们只是渲染蒙版的样子(在右侧),我们可以看到它是如何工作的。

svg {
  width: 300px;
}

.purple {
  fill: rebeccapurple;
}

.reduce-me {
  mask: url(#reducer);
}

#reduce-amount {
  stroke-width: 10px;
}
<svg viewBox="0 0 100 100">
  <path class="purple"
        d="M 50,10 Q 100,10, 50,50 Q 0,90, 50,90 
           Q 100,90, 50,50 Q 0,10, 50,10 Z"/>
</svg>


<svg viewBox="0 0 100 100">
  <defs>
    <!-- the shared path that is used by both the purple path and the mask -->
    <path id="shared-path"
          id="p" d="M 50,10 Q 100,10, 50,50 Q 0,90, 50,90
                    Q 100,90, 50,50 Q 0,10, 50,10 Z" />
  </defs>

  <use id="reduce-amount" xlink:href="#shared-path"
       fill="white" stroke="black"/>
</svg>

我们使用与面具相同的形状。然而,面具周围有一个厚厚的黑色笔触。面具中的黑色使事物变得透明。面具的其余部分是白色的,仍然可见。

您可以通过更改.reduce-amount 类中的stroke-width 值来更改形状缩减量。

这种方法的缺点是: 1. 你需要为每一个不同的路径形状做一个遮罩 2.不能设置缩小尺寸形状的笔触样式。但是,您可以通过覆盖具有不同减少量的两条路径来模拟笔触颜色。

【讨论】:

    【解决方案2】:

    您可以扩展过滤器来完成这项工作。似乎有一个错误侵蚀了填充形状的图案 - 它没有正确采用半径中的 alpha 通道的最小值。但是,如果您从 SourceAlpha 而不是 SourceGraphic 开始,然后使用组件传输创建掩码,它似乎可以工作。

               <svg>
                <defs>
                    <pattern id="circ" x="0" y="0" width="30" height="30" patternUnits="userSpaceOnUse">
                        <rect fill="blue" width="100%" height="100%" />
                        <circle cx="10" cy="10" r="10" fill="green" />
                    </pattern>
                  <filter id="erode3">
    <feMorphology in="SourceAlpha" result="eroded"
    operator="erode" radius="10"/>
                 <feComponentTransfer>
                   <feFuncR type="discrete" tableValues="1 0"/>
                   <feFuncG type="discrete" tableValues="1 0"/>
                   <feFuncB type="discrete" tableValues="1 0"/>
                  </feComponentTransfer>
                <feComposite operator ="in" in="SourceGraphic"/>
    </filter>
    
                    <path id="thing" d="M 0,0 H 50 A 35,35 0 1 0 100,50 V 75 C 50,125 0,85 0,85 Z" />
                </defs>
                <use href="#thing" fill="url(#circ)" width="400" height="400" filter="url(#erode3)"/>
                <use x="100" href="#thing" filter="url(#erode)" fill="url(#circ)" width="400" height="400" />
            </svg>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-04
      • 2019-07-14
      • 1970-01-01
      • 1970-01-01
      • 2013-12-19
      • 2012-05-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多