如何使用SVG Filter填充两条Polyline之间的区域?
解决SVG滤镜填充两条Polyline之间区域的问题
问题根源
你原代码的核心错误是在滤镜定义中直接使用了<use>元素——SVG滤镜的<filter>标签内只能包含滤镜基元(所有以fe开头的元素,如feImage、feComposite等),普通图形元素或<use>无法在滤镜内部生效,这就是填充和feComposite操作无效的原因。
正确实现方式
我们可以通过滤镜基元来实现你的差集填充思路,具体步骤如下:
- 使用
feImage引用内部的#inner图形,将其转换为滤镜可处理的图像源 - 以填充后的
#outer作为源图形,通过feComposite的out操作计算两者的差集 - 将差集结果作为最终填充,置于原Polyline下方
完整代码
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"> <defs> <filter id="fillBetween"> <!-- 引入inner图形并存储为中间结果 --> <feImage href="#inner" result="innerFill" /> <!-- 计算outer填充与inner填充的差集 --> <feComposite in="SourceGraphic" in2="innerFill" operator="out" /> </filter> </defs> <!-- 保留原Polyline不变 --> <polyline id="outer" points="50.0,10.0 90.0,90.0 10.0,90.0 50.0,10.0" stroke="black" stroke-width="1" fill="none" /> <polyline id="inner" points="35.0,50.0 65.0,50.0 50.0,80.0 35.0,50.0" stroke="black" stroke-width="1" fill="none" /> <!-- 应用滤镜的填充层(置于原图形下方) --> <use href="#outer" filter="url(#fillBetween)" fill="green" /> </svg>
代码说明
feImage href="#inner":将内部Polyline转换为滤镜可用的图像,result属性将其命名为innerFill供后续步骤调用feComposite operator="out":该操作会保留第一个输入(SourceGraphic,即填充后的outer)中,不在第二个输入(innerFill)内的区域,正好对应两条Polyline之间的部分- 原Polyline未做任何修改,且位于填充层上方,因此边框会正常显示
补充:更简洁的非滤镜实现(可选)
如果不限制必须使用滤镜,用mask可以更直观地实现效果:
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"> <defs> <mask id="betweenMask"> <rect width="100" height="100" fill="white" /> <use href="#inner" fill="black" /> </mask> </defs> <rect width="100" height="100" fill="green" mask="url(#betweenMask)" /> <polyline id="outer" points="50.0,10.0 90.0,90.0 10.0,90.0 50.0,10.0" stroke="black" stroke-width="1" fill="none" /> <polyline id="inner" points="35.0,50.0 65.0,50.0 50.0,80.0 35.0,50.0" stroke="black" stroke-width="1" fill="none" /> </svg>
内容的提问来源于stack exchange,提问作者tfc
相关产品推荐
相关产品推荐

