如何实现SVG位移滤镜的流畅湍流效果(类似Pixi.js重复模式)
实现SVG滤镜的流畅轴向流动湍流效果
问题根源
你当前的代码中current持续自增,导致baseFrequency的Y分量无限增大,位移纹理不断累积偏移,最终出现堆叠效果。要实现类似Pixi.js位移滤镜的repeat模式,需要让湍流纹理无缝循环,同时限制baseFrequency的范围。
解决方案
1. 修改SVG滤镜配置
将stitchTiles设为stitch(实现无缝拼接),移除不必要的feColorMatrix动画(若无需颜色变化):
<svg width="0" height="0" style="position:absolute;"> <filter id="flow-filter"> <feTurbulence id="turb" type="turbulence" baseFrequency="0.5 0" numOctaves="3" stitchTiles="stitch" result="turbulence"/> <feDisplacementMap in="SourceGraphic" in2="turbulence" xChannelSelector="R" yChannelSelector="G" scale="50"/> </filter> </svg>
2. 调整JavaScript动画逻辑
使用取模运算限制baseFrequency的循环范围,避免无限累加:
const turb = document.getElementById('turb'); const maxFreq = 0.5; // Y分量的最大频率值,控制纹理密度 let current = 0; const step = 0.001; // 流动速度,值越大流动越快 function animate() { current += step; // 取模让频率值在0到maxFreq之间循环 const yFreq = current % maxFreq; turb.setAttribute('baseFrequency', `0.5 ${yFreq.toFixed(6)}`); requestAnimationFrame(animate); } animate();
3. CSS应用(保持不变)
img { width: 100%; filter: url(#flow-filter); }
关键说明
stitchTiles="stitch":确保湍流纹理边缘无缝拼接,循环时不会出现断层。- 取模运算:让
baseFrequency的目标分量在0到设定最大值之间循环,避免位移累积。 - 参数调整:
maxFreq:控制纹理的密度,值越大纹理越细密。step:控制流动速度,值越大流动越快。scale:调整位移幅度,值越大图片变形越明显。
- 水平流动适配:若需要水平方向流动,只需将
baseFrequency的X分量设为循环值,Y分量固定,例如:baseFrequency="${xFreq.toFixed(6)} 0"
内容的提问来源于stack exchange,提问作者Mr.Coder
相关产品推荐
相关产品推荐

