如何无需重复路径实现带透明度的SVG滤镜合成?
无需重复路径实现带透明度描边与纯色填充的无混合合成
当然有更简洁的方案——不用复制路径,靠SVG滤镜里的颜色矩阵和合成操作就能搞定。核心思路是从带透明度的描边中提取出不透明的轮廓蒙版,用它裁切纯色填充,再叠加原描边即可。
优化后的代码
<svg width="120" height="120" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <defs> <!-- 只保留一组带透明度的描边路径 --> <path id="strokes" d="M20,10 L60,60 M50,10 L90,90" stroke="rgb(112,48,160)" stroke-width="15" stroke-opacity="0.5" fill="none" /> <filter id="filter" color-interpolation-filters="sRGB"> <feFlood flood-color="blue" x="0" y="0" width="100" height="100" result="flood" /> <!-- 引入原带透明度的描边 --> <feImage xlink:href="#strokes" x="0" y="0" width="100" height="100" result="lines" /> <!-- 将描边转换为纯Alpha蒙版(保留轮廓,去除颜色和透明度) --> <feColorMatrix in="lines" type="matrix" values=" 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0" result="strokeMask" /> <!-- 用蒙版裁切填充:去掉填充中描边覆盖的区域 --> <feComposite in="flood" in2="strokeMask" operator="out" result="cut" /> <!-- 叠加原带透明度的描边 --> <feComposite in="lines" in2="cut" operator="over" result="final" /> </filter> </defs> <rect x="15" y="15" width="105" height="105" fill="white" stroke="red" stroke-width="2" id="backdrop" /> <rect x="20" y="20" width="100" height="100" fill="rgb(0, 128, 0)" id="compare" /> <rect width="100" height="100" filter="url(#filter)" id="partialTransparentShape" /> </svg>
关键步骤说明
feColorMatrix转换蒙版:通过矩阵参数把描边的RGB通道清零,只保留Alpha通道并将其放大到完全不透明(最后一行的255是Alpha的缩放系数),这样就得到了和原描边轮廓完全一致的不透明蒙版,替代了原来的纯色路径。- 裁切填充:用
feComposite的out操作,把纯色填充中蒙版覆盖的区域挖掉,避免和后续叠加的描边混合。 - 叠加原描边:最后把带透明度的原描边直接放在裁切后的填充上,完美保留原本的颜色和透明度。
内容的提问来源于stack exchange,提问作者Meihua
相关产品推荐
相关产品推荐

