当feComposite的一个输入不属于滤镜作用对象时该如何使用?
SVG重叠区域阴影裁剪解决方案
你之前直接给#shadow加feComposite无法生效,是因为单个元素的滤镜默认只能获取当前元素的像素作为输入,必须主动引入#ani的图形作为第二个输入源,才能完成跨元素的区域合成。
实现逻辑
通过feImage标签分别读取两个元素的像素,先对#shadow做模糊处理,再用feComposite的in操作符取两个元素的重叠区域,仅保留该范围内的模糊阴影即可。
可直接运行的修改后代码
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"> <defs> <filter id="clipShadow" x="-20%" y="-20%" width="140%" height="140%"> <!-- 引入#ani作为裁剪遮罩 --> <feImage href="#ani" result="aniMask" /> <!-- 引入#shadow并做模糊生成阴影 --> <feImage href="#shadow" result="rawShadow" /> <feGaussianBlur in="rawShadow" stdDeviation="3" result="blurShadow" /> <!-- 取交集,仅保留重叠区域的阴影 --> <feComposite in="blurShadow" in2="aniMask" operator="in" /> </filter> </defs> <style> :root { --len: 100; /* 可替换为实际path长度 */ } #ani { stroke: #000; stroke-width: 2; fill: none; stroke-dasharray: var(--len); stroke-dashoffset: var(--len); transition: stroke-dashoffset 1s ease; } /* 隐藏原始shadow,仅通过滤镜输出裁剪后的阴影 */ #shadow { stroke: #000; stroke-width: 2; visibility: hidden; } </style> <script> document.onclick = () => { // 修正原有代码的笔误 atyle -> style document.getElementById("ani").style.strokeDashoffset = "0"; } </script> <!-- 渲染裁剪后的阴影 --> <rect fill="none" width="100%" height="100%" filter="url(#clipShadow)" /> <!-- 原始动画路径 --> <path id="ani" d="M10 10 L100 10 L100 100 L10 100 Z" /> <!-- 重叠的shadow线条 --> <line id="shadow" x1="0" y1="50" x2="110" y2="50" /> </svg>
注意事项
- 若需要兼容旧版SVG标准,将
feImage的href属性替换为xlink:href即可 - 滤镜的
x/y/width/height设置了20%的扩展空间,避免模糊后的阴影被截断,可根据实际效果调整数值 - 如果需要#ani和阴影同时显示,保持现有结构即可;如果不需要显示#ani的原始描边,直接给#ani设置
visibility:hidden即可
内容的提问来源于stack exchange,提问作者user16896125
相关产品推荐
相关产品推荐

