编程

SVG 滤镜简直太棒了!

3 2026-07-24 20:08:00

最近我在浏览 Haley Park 的网站,感觉非常可爱,设计也很精美。不过,最吸引我的是其中一段文字上的水波纹效果。

正如你所见,这段文字呈现出美丽的水波纹效果。我深入研究了源代码,发现它竟然是用 SVG 滤镜实现的!

于是,我了解了一些关于 SVG 滤镜的知识,以下是我的发现。

SVG 滤镜是一​​种强大的方法,可以将图形效果应用于 SVG 元素。它们也可以通过 CSS 的 filter 属性应用于 HTML 元素。如果没有 SVG 滤镜,要实现像水波纹这样复杂的视觉效果,就需要使用图片或复杂的 JavaScript 动画。

要重现水波纹效果,首先要定义要应用效果的元素。在本例中,它是一个简单的段落,文本为“Breathe”(呼吸)。

<p class="ripple-text">
    Breathe
</p>

接下来定义你想要应用的 SVG 滤镜。

<svg style="position: absolute; width: 0px; height: 0px; pointer-events: none;">
    <filter id="water-ripple">
        <feTurbulence type="fractalNoise" baseFrequency="0.05" numOctaves="2" result="ripple">
            <animate attributeName="baseFrequency" dur="10s" values="0.02;0.05;0.02" repeatCount="indefinite"></animate>
        </feTurbulence>
        <feDisplacementMap in="SourceGraphic" in2="ripple" scale="5"></feDisplacementMap>
    </filter>
</svg>

如您所见,我们可以使用 id 为 water-ripple<filter> 元素定义一个滤镜。

在滤镜内部,我们使用了两个滤镜基元:

  • <feTurbulence> 元素 - 用于创建噪声纹理,然后通过动画模拟水波纹效果。
  • <feDisplacementMap> 元素 - 用于将湍流效果应用于文本。

这些滤镜有很多参数可以调整,以实现不同的效果。

例如,在 <feTurbulence> 元素中,我们将 type 设置为 fractalNoise,这将创建一个分形噪声图案。baseFrequency 控制噪声的频率,numOctaves 控制噪声的复杂度。

类似地,对于 <feDisplacementMap> 元素,in 属性指定输入图像(在本例中为原始文本),in2 属性指定由 <feTurbulence> 创建的湍流效果。 scale 属性控制应用于文本的位移量。

此外,通过将 SVG 的宽度和高度设置为 0 并将其定位为绝对定位,可以隐藏该 SVG。

过滤器元素名称中的“fe”代表“滤镜效果(FILTER EFFECT)”。

最后,使用 CSS 中过滤器的 id 将滤镜应用到文本上。

.ripple-text {
    filter: url(#water-ripple);
    font-size: 3rem;
    font-weight: bold;
}

搞定!现在,你已经使用 SVG 滤镜为文本添加了漂亮的水波纹效果。

我发现了一个很棒的 SVG 滤镜实验平台,你可以在这里尝试不同的滤镜组件,并实时查看效果。你可以叠加多个滤镜组件,更改它们的参数,从而创建复杂的效果。

如果你想了解更多关于 SVG 滤镜的知识,可以查看 MDN 上关于 SVG 滤镜的文档,那里有关于如何使用它们的全面指南。