具有填充图案的 SVG 缩减路径



我尝试绘制一个具有必须缩小的路径的形状,就像在这个解决方案中一样 查找平行或偏移 SVG 路径 我使用过滤器"侵蚀",但对于图案它不起作用:图案变形。

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

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

<!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 {
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.您无法设置缩小尺寸形状的描边样式。 但是,您可以通过叠加两条具有不同缩减量的路径来模拟描边颜色。

您可以扩展过滤器以使其正常工作。似乎有一个错误侵蚀图案填充的形状 - 它没有正确获取半径中 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>

最新更新