如何用SVG的feTurbulence实现水平移动的湍流滤镜?
实现水平移动的滤镜
当然可以实现水平移动的<feTurbulence>滤镜——虽然它本身没有直接控制位置的属性,但通过组合SVG滤镜和动画,就能轻松达成无限循环的水平移动效果。以下是两种实用方案:
方案一:用<feOffset>配合动画平移湍流图案
先通过<feTurbulence>生成噪声纹理,再用<feOffset>滤镜将纹理水平偏移,最后给feOffset的dx属性做循环动画,让纹理无缝移动。
<svg width="400" height="200" xmlns="http://www.w3.org/2000/svg"> <filter id="movingTurbulence"> <!-- 生成基础湍流噪声 --> <feTurbulence type="turbulence" baseFrequency="0.05" numOctaves="2" seed="1"/> <!-- 给偏移量添加动画 --> <feOffset id="offsetAnim" dx="0" dy="0"/> <animate xlink:href="#offsetAnim" attributeName="dx" values="0; 400; 0" <!-- 偏移范围和SVG宽度一致,实现无缝循环 --> dur="5s" repeatCount="indefinite"/> </filter> <!-- 应用滤镜的容器 --> <rect width="100%" height="100%" filter="url(#movingTurbulence)"/> </svg>
说明:
dx的动画值设为SVG的宽度(示例中是400),这样纹理移动到边界时刚好衔接初始状态,实现无限循环。- 调整
baseFrequency可改变噪声的密度,numOctaves控制噪声的复杂度,dur控制移动速度。
方案二:用<feDisplacementMap>结合移动渐变实现流动效果
利用水平移动的线性渐变作为位移参考,让<feDisplacementMap>基于渐变的亮度值偏移湍流图案,这种方法能做出更自然的流动感。
<svg width="400" height="200" xmlns="http://www.w3.org/2000/svg"> <!-- 定义水平移动的线性渐变 --> <linearGradient id="moveGrad" x1="0%" x2="100%"> <stop offset="0%" stop-color="#000"/> <stop offset="100%" stop-color="#fff"/> <!-- 动画渐变的起始/结束位置,实现水平移动 --> <animate attributeName="x1" values="0%; 100%; 0%" dur="5s" repeatCount="indefinite"/> <animate attributeName="x2" values="100%; 200%; 100%" dur="5s" repeatCount="indefinite"/> </linearGradient> <filter id="displaceTurbulence"> <feTurbulence type="turbulence" baseFrequency="0.05" numOctaves="2" seed="1"/> <!-- 用移动的渐变作为位移源,scale控制偏移强度 --> <feDisplacementMap in2="SourceGraphic" in="previous" scale="50"/> </filter> <!-- 填充渐变并应用滤镜 --> <rect width="100%" height="100%" fill="url(#moveGrad)" filter="url(#displaceTurbulence)"/> </svg>
说明:
scale值越大,湍流图案的偏移幅度越大,可根据需求调整。- 渐变的动画范围要覆盖SVG容器,确保移动时不会出现断层。
内容的提问来源于stack exchange,提问作者IWannaDance
相关产品推荐
相关产品推荐

