给一个圆添加柔和的投影?让一张图片变成黑白?制作一个毛玻璃效果的卡片?或者让文字像水面一样波动?
在 CSS 里,你可能需要 box-shadow、filter 或 backdrop-filter。但当效果变得更复杂——比如方向性阴影、颜色矩阵变换、甚至流体扭曲——CSS 就显得力不从心了。
这时候,SVG 滤镜就该登场了。
SVG 滤镜就像一套“图形特效处理器”。它由多个可组合的“效果单元”(官方叫滤镜基元,filter primitives)串联而成,每个单元负责一种特定的图像处理——模糊、偏移、颜色变换、扭曲……你可以像搭积木一样把它们拼在一起,创造出 CSS 无法实现的视觉效果。
这篇文章会从零开始,带你理解 SVG 滤镜的工作方式,掌握最常用的几个滤镜基元,最后用一个综合案例把它们串起来。
一、滤镜是什么?先看一个最简单的例子
在 SVG 里,滤镜通过 <filter> 元素定义,通常放在 <defs> 区块中。定义好之后,用 filter="url(#滤镜ID)" 把它“贴”到目标图形上。
来看一个最基础的模糊效果:
<svg width="230" height="120" xmlns="http://www.w3.org/2000/svg">
<!-- 1. 在 defs 中定义滤镜 -->
<defs>
<filter id="blurMe">
<feGaussianBlur in="SourceGraphic" stdDeviation="5" />
</filter>
</defs>
<!-- 2. 左边是不加滤镜的圆(参照物) -->
<circle cx="60" cy="60" r="50" fill="green" />
<!-- 3. 右边是加了滤镜的圆 -->
<circle cx="170" cy="60" r="50" fill="green" filter="url(#blurMe)" />
</svg>代码很简单,但包含了 SVG 滤镜的三个核心要素:
<filter>:滤镜的“容器”,用 id 给它起个名字。
滤镜基元:这里用的是 <feGaussianBlur>,负责执行“高斯模糊”这个具体操作。
filter 属性:在目标元素上通过 url(#id) 引用滤镜。
in="SourceGraphic" 是什么意思?
每个滤镜基元都需要一个“输入”。SourceGraphic 表示“原始图形本身”——也就是那个绿色的圆。基元对输入做处理,然后输出结果。后面你会看到,一个基元的输出可以成为下一个基元的输入,这就是“串联”的秘密。
二、滤镜的“边界盒子”:为什么效果被裁剪了?
先停一下,说一个新手最容易遇到的坑。
有时候你给图形加了投影或模糊,发现效果被裁掉了一半——阴影只显示了一小块,模糊的边缘像被剪刀剪过一样整齐。
这是因为 <filter> 默认的作用区域是“目标元素的边界框”(filterUnits="objectBoundingBox"),而模糊或偏移产生的效果会超出这个边界框。
解决方案:手动扩大滤镜的作用区域。
<svg width="230" height="120" xmlns="http://www.w3.org/2000/svg">
<defs>
<!--
x/y/width/height 扩大滤镜区域:
阴影向外扩散时不会被裁切
-->
<filter id="dropShadow" x="-20%" y="-20%" width="140%" height="140%">
<!-- 1. 对图形的 Alpha 通道做模糊,得到软边阴影 -->
<feGaussianBlur in="SourceAlpha" stdDeviation="5" result="blur" />
<!-- 2. 将模糊结果偏移,形成落影位置 -->
<feOffset in="blur" dx="6" dy="6" result="offsetBlur" />
<!-- 3. 先画阴影,再叠回原图 -->
<feMerge>
<feMergeNode in="offsetBlur" />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
</defs>
<!-- 左边:不加滤镜的参照 -->
<circle cx="60" cy="55" r="40" fill="#3498db" />
<!-- 右边:应用 dropShadow -->
<circle cx="170" cy="55" r="40" fill="#3498db" filter="url(#dropShadow)" />
</svg>x、y、width、height 定义了滤镜的“画布”大小。这里把左上角向左上各扩展 20%,宽高各放大到 140%,给模糊和阴影留出足够的“呼吸空间”。
经验法则:凡是涉及 feGaussianBlur(模糊)或 feOffset(偏移)的滤镜,都顺手把 filter 的边界扩大一些,能省去很多排查时间。
filterUnits 的两种模式:
objectBoundingBox(默认):x/y/width/height 是元素边界框的百分比或分数。灵活但不够直观。
userSpaceOnUse:x/y/width/height 使用当前用户坐标系的像素值,通常就是 SVG 视口的像素。更直观可控。
三、常用的滤镜基元:你的“特效工具箱”
SVG 提供了大约 20 种滤镜基元。对初中级开发者来说,掌握下面这 6 个,就能覆盖 90% 以上的日常需求。
fe = Filter Effect(滤镜效果)
SVG 滤镜原语都用 fe 前缀,表示它们是滤镜效果元素,例如:
feGaussianBlur — 高斯模糊滤镜效果
feOffset — 偏移滤镜效果
feMerge / feMergeNode — 合并滤镜效果
3.1 <feGaussianBlur> —— 高斯模糊
作用:让图形变模糊,产生“柔焦”效果。
<feGaussianBlur in="SourceGraphic" stdDeviation="5" />stdDeviation:模糊强度,数值越大越模糊。可以写两个值(如 "5 10"),分别控制水平和垂直方向的模糊程度。
典型用途:制作阴影的“模糊层”、毛玻璃效果、背景虚化。
3.2 <feOffset> —— 位移
作用:把图像沿 x 轴和 y 轴方向平移。
<feOffset in="blur" dx="4" dy="4" result="offsetBlur" />dx / dy:水平和垂直偏移量(正数向右/向下)。
典型用途:配合模糊制作投影——先把原图模糊,再偏移,就得到了阴影的“形状”。
3.3 <feMerge> —— 合并图层
作用:把多个图像“叠”在一起。
<feMerge>
<feMergeNode in="offsetBlur" />
<feMergeNode in="SourceGraphic" />
</feMerge><feMerge> 里面可以放多个 <feMergeNode>, 先写的在底层,后写的在上层。上面的例子中,offsetBlur(阴影)在下面,SourceGraphic(原始图形)在上面——正好形成一个“投影在底下、原图在上面”的层次关系。
典型用途:把原始图形和它的阴影、发光等效果合成在一起。
3.4 <feColorMatrix> —— 颜色矩阵变换
作用:对每个像素的颜色做矩阵乘法,实现色相旋转、饱和度调整、灰度化、颜色替换等效果。
<!-- 把彩色图片变成黑白 -->
<feColorMatrix type="saturate" values="0" />
<!-- 色相旋转 180° -->
<feColorMatrix type="hueRotate" values="180" />
<!-- 反色(自定义 4×5 矩阵)-->
<feColorMatrix type="matrix" values="
-1 0 0 0 1
0 -1 0 0 1
0 0 -1 0 1
0 0 0 1 0"/>type="saturate":饱和度控制,values="0" 就是完全黑白。
type="hueRotate":色相旋转,角度 0~360。
type="matrix":最强大的模式,用 4×5 矩阵自定义颜色变换。每一行对应输出的 R/G/B/A,每一列对应输入的 R/G/B/A 和一个常数偏移。
质感提示:type="matrix" 的 4×5 矩阵看似可怕,其实规律很简单。第一行决定新红色怎么算,第二行决定新绿色……最后一列是常数偏移。复古色调(Sepia)的矩阵不是魔法,而是前人总结的经验值。实际开发中可以用在线工具实时调整矩阵参数。
典型用途:图片滤镜(黑白、复古)、图标颜色动态替换、特殊色调效果。
完整示例
<div class="row">
<figure>
<svg width="160" height="140" xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="70" r="36" fill="#e74c3c" />
<circle cx="80" cy="70" r="36" fill="#2ecc71" />
<circle cx="110" cy="70" r="36" fill="#3498db" />
</svg>
<figcaption>原图(无滤镜)</figcaption>
</figure>
<figure>
<svg width="160" height="140" xmlns="http://www.w3.org/2000/svg">
<defs>
<filter id="toGray">
<!-- 把彩色图片变成黑白 -->
<feColorMatrix type="saturate" values="0" />
</filter>
</defs>
<g filter="url(#toGray)">
<circle cx="50" cy="70" r="36" fill="#e74c3c" />
<circle cx="80" cy="70" r="36" fill="#2ecc71" />
<circle cx="110" cy="70" r="36" fill="#3498db" />
</g>
</svg>
<figcaption>saturate=0(去饱和 / 黑白)</figcaption>
</figure>
<figure>
<svg width="160" height="140" xmlns="http://www.w3.org/2000/svg">
<defs>
<filter id="hueFlip">
<!-- 色相旋转 180° -->
<feColorMatrix type="hueRotate" values="180" />
</filter>
</defs>
<g filter="url(#hueFlip)">
<circle cx="50" cy="70" r="36" fill="#e74c3c" />
<circle cx="80" cy="70" r="36" fill="#2ecc71" />
<circle cx="110" cy="70" r="36" fill="#3498db" />
</g>
</svg>
<figcaption>hueRotate=180(互补色)</figcaption>
</figure>
<figure>
<svg width="160" height="140" xmlns="http://www.w3.org/2000/svg">
<defs>
<filter id="invert">
<!-- 反色(自定义 4×5 矩阵)-->
<feColorMatrix type="matrix" values="
-1 0 0 0 1
0 -1 0 0 1
0 0 -1 0 1
0 0 0 1 0"/>
</filter>
</defs>
<g filter="url(#invert)">
<circle cx="50" cy="70" r="36" fill="#e74c3c" />
<circle cx="80" cy="70" r="36" fill="#2ecc71" />
<circle cx="110" cy="70" r="36" fill="#3498db" />
</g>
</svg>
<figcaption>matrix 反色(RGB 取反)</figcaption>
</figure>
</div>
3.5 <feTurbulence> —— 噪声/湍流
作用:用 Perlin 噪声算法生成“随机纹理”——像云雾、大理石、水波纹一样的自然图案。
<feTurbulence type="turbulence" baseFrequency="0.05" numOctaves="2" result="turbulence" />type:turbulence(湍流,更激烈)或 fractalNoise(分形噪声,更平滑)。
baseFrequency:噪声的“频率”,值越小纹理越平滑、越大越细碎。可以写两个值分别控制 x/y 方向。
numOctaves:噪声的“细节层次”,值越大纹理越丰富(但计算量也越大)。
技术细节:baseFrequency 可以理解为"缩放级别",numOctaves 是"细节滑块"。baseFrequency=0.01 是宏观的云层,0.1 就变成细碎的颗粒噪点了。在性能敏感场景下,numOctaves 不要超过 3,否则会明显影响渲染性能。
典型用途:生成云朵、火焰、水波纹、大理石纹理等有机效果。
大理石纹理示例:
<figure>
<svg width="320" height="220" xmlns="http://www.w3.org/2000/svg">
<defs>
<filter id="marble" x="0" y="0" width="100%" height="100%" color-interpolation-filters="sRGB">
<!-- Perlin 湍流噪声:baseFrequency 越小纹理越大,numOctaves 越大层次越丰富 -->
<feTurbulence type="turbulence" baseFrequency="0.05" numOctaves="2" seed="7" result="turbulence" />
<!-- 把 RGB 噪声压成灰阶,露出深浅相间的天然条纹 -->
<feColorMatrix in="turbulence" type="saturate" values="0" result="grayNoise" />
<!-- 提高对比,让“矿脉”更清晰 -->
<feComponentTransfer in="grayNoise" result="veins">
<feFuncR type="gamma" amplitude="1" exponent="0.55" offset="0" />
<feFuncG type="gamma" amplitude="1" exponent="0.55" offset="0" />
<feFuncB type="gamma" amplitude="1" exponent="0.55" offset="0" />
</feComponentTransfer>
<!-- 映射成大理石色:浅底 + 青灰/墨色纹理 -->
<feColorMatrix in="veins" type="matrix" values="
0.55 0.20 0.10 0 0.38
0.48 0.22 0.10 0 0.34
0.42 0.18 0.12 0 0.30
0 0 0 1 0" />
</filter>
</defs>
<rect width="320" height="220" rx="8" filter="url(#marble)" />
</svg>
<figcaption>矩形表面:大理石纹理</figcaption>
</figure>
3.6 <feDisplacementMap> —— 位移映射
作用:根据另一张图(in2)的像素值,把当前图(in)的像素“挤来挤去”,产生扭曲变形。
<feDisplacementMap in="SourceGraphic" in2="turbulence" scale="50"
xChannelSelector="R" yChannelSelector="G" />in2:用作“位移地图”的图像(通常来自 feTurbulence)。
scale:位移强度,数值越大变形越剧烈。
xChannelSelector / yChannelSelector:用 in2 的哪个颜色通道来控制 x/y 方向的位移。
常见坑提示:in2 必须指向一个存在的 result。如果 feTurbulence 的 result="noise",那么 feDisplacementMap 的 in2 就必须是 "noise"。写错了滤镜会静默失败,很难调试。
典型用途:水波纹、液体扭曲、文字液化、玻璃折射效果。
湍流示例:
<figure>
<svg width="280" height="180" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="bars2" x1="0" y1="0" x2="1" y2="0">
<stop offset="0%" stop-color="#e74c3c" />
<stop offset="25%" stop-color="#f1c40f" />
<stop offset="50%" stop-color="#2ecc71" />
<stop offset="75%" stop-color="#3498db" />
<stop offset="100%" stop-color="#9b59b6" />
</linearGradient>
<filter id="displace" x="-20%" y="-20%" width="140%" height="140%">
<!-- 生成 Perlin 噪声,result 名称供下一步 in2 引用 -->
<feTurbulence type="turbulence" baseFrequency="0.02" numOctaves="3" seed="2" result="turbulence" />
<!-- 用噪声的 R/G 通道分别推开原图的 X/Y 像素 -->
<feDisplacementMap in="SourceGraphic" in2="turbulence" scale="50"
xChannelSelector="R" yChannelSelector="G" />
</filter>
</defs>
<g filter="url(#displace)">
<rect width="280" height="180" fill="url(#bars2)" />
<text x="140" y="105" text-anchor="middle" font-size="56" font-weight="700" fill="#fff">SVG</text>
</g>
</svg>
<figcaption>feTurbulence + feDisplacementMap(scale=50)</figcaption>
</figure>
四、组合的艺术:把基元串起来
单个滤镜基元的效果有限。真正的威力来自于把它们串联起来——一个基元的输出成为下一个基元的输入。
这里的关键是 result 和 in 属性:
result:给当前基元的输出起个名字。
in:指定当前基元的输入来源(可以是 SourceGraphic、SourceAlpha,或者前面某个基元的 result)。
案例一:手动打造投影效果
虽然 SVG 有专门的 <feDropShadow> 元素,但理解手动实现的过程能帮你真正掌握“串联”的思路:
<filter id="manualShadow" x="-20%" y="-20%" width="140%" height="140%">
<!-- 第1步:提取图形的透明度通道,生成模糊 -->
<feGaussianBlur in="SourceAlpha" stdDeviation="4" result="blur" />
<!-- 第2步:把模糊结果向右下偏移 -->
<feOffset in="blur" dx="4" dy="4" result="offsetBlur" />
<!-- 第3步:把阴影和原始图形叠在一起 -->
<feMerge>
<feMergeNode in="offsetBlur" />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>流程图:
原始图形 → 提取透明度通道 → 模糊 → 偏移 → 和原始图形合并 → 最终效果注意这里用的是 SourceAlpha(图形的透明度通道)而不是 SourceGraphic(完整图形)。为什么?因为阴影只需要“形状”,不需要颜色。用透明度通道生成的阴影是纯黑轮廓,后续可以任意着色。
案例二:发光效果(Glow)
把上面的投影改一改——不偏移,直接叠加,就变成了发光效果:
<figure>
<svg width="280" height="180" xmlns="http://www.w3.org/2000/svg">
<defs>
<filter id="glow" x="-50%" y="-50%" width="200%" height="200%">
<!-- 生成模糊的发光层 -->
<feGaussianBlur in="SourceGraphic" stdDeviation="6" result="blur" />
<!-- 把原图和发光层叠加 -->
<feMerge>
<feMergeNode in="blur" />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
</defs>
<rect width="280" height="180" fill="#11141a" rx="8" />
<g filter="url(#glow)">
<circle cx="80" cy="90" r="36" fill="#00e5ff" />
<text x="180" y="102" text-anchor="middle" font-size="36" font-weight="700" fill="#fff">GLOW</text>
</g>
</svg>
<figcaption>feGaussianBlur + feMerge(stdDeviation=6)</figcaption>
</figure>注意这里把滤镜边界扩大到 200%,因为发光效果需要更多的"呼吸空间"。如果想改变发光的颜色,可以在模糊之后加一个 <feColorMatrix> 或 <feFlood> 来着色。

五、综合案例:水波纹扭曲效果
现在把前面学的几个基元组合起来,做一个“文字在水面波动”的效果:
<svg width="400" height="200" viewBox="0 0 400 200" xmlns="http://www.w3.org/2000/svg">
<defs>
<!-- 水波纹滤镜 -->
<filter id="waterRipple" x="-20%" y="-20%" width="140%" height="140%">
<!-- 1. 生成噪声纹理 -->
<feTurbulence type="turbulence" baseFrequency="0.02 0.06"
numOctaves="3" result="noise" />
<!-- 2. 用噪声纹理扭曲文字 -->
<feDisplacementMap in="SourceGraphic" in2="noise"
scale="20" xChannelSelector="R" yChannelSelector="G" />
</filter>
</defs>
<!-- 应用滤镜的文字 -->
<text x="200" y="120" font-size="48" font-weight="bold"
fill="#1a73e8" text-anchor="middle" filter="url(#waterRipple)">
波 动
</text>
</svg>原理拆解:
<feTurbulence> 生成一个随机噪声图。
<feDisplacementMap> 用这个噪声图“推挤”文字的每个像素。
baseFrequency="0.02 0.06" 让水平方向波纹更宽、垂直方向更密,模拟真实水面的涟漪。
scale="20" 控制扭曲强度。
如果把这个效果做成动画——让 baseFrequency 或 scale 随时间变化——就能得到流动的水面效果。
六、在 CSS 中使用 SVG 滤镜
SVG 滤镜不只属于 SVG 图形。你可以把它应用到任何 HTML 元素上,通过 CSS 的 filter 属性引用:
<!-- 在 HTML 中定义 SVG 滤镜(隐藏起来) -->
<svg width="0" height="0" aria-hidden="true">
<defs>
<filter id="glassEffect">
<feGaussianBlur in="SourceGraphic" stdDeviation="8" />
</filter>
</defs>
</svg><!-- 在 CSS 中应用到任意元素 -->
<style>
.card {
filter: url(#glassEffect);
}
</style><!-- 使用 -->
<div class="card">毛玻璃卡片</div>注意事项:
为了让隐藏的 <svg> 不影响布局,可以设置 width="0" height="0" 并用 position: fixed 把它移出文档流。
SVG 滤镜可以和 CSS 滤镜 链式使用:filter: url(#myFilter) blur(2px)。
涉及颜色运算的滤镜,建议加上 color-interpolation-filters="sRGB",以保证跨浏览器效果一致。
SVG 滤镜在现代浏览器中支持良好(Chrome 53+、Firefox 35+、Safari 10.1+、Edge 79+),但复杂滤镜在 Safari 中性能较差。
七、性能优化:用得起还得用得好
SVG 滤镜的本质是像素级运算——浏览器需要先把矢量图形光栅化为临时位图,再对每个像素做数学变换。这意味着复杂滤镜是”性能重灾区“,不当地使用会严重拖慢页面帧率。
7.1 能用 CSS 滤镜的,就别用 SVG
CSS 的 filter 属性(blur()、grayscale()、drop-shadow()、backdrop-filter 等)由浏览器厂商高度优化,通常跑在 GPU 上。对于简单模糊、灰度、投影,优先用 CSS。
<!-- 推荐:CSS 简洁高效 -->
.blurred { filter: blur(5px); }
.gray { filter: grayscale(100%); }
.shadowed { filter: drop-shadow(0 4px 8px rgba(0,0,0,.3)); }
<!-- 仅当 CSS 做不到时,再用 SVG 滤镜 -->7.2 严格收缩滤镜作用域
这是性能优化中投入产出比最高的一项。默认情况下,滤镜可能会处理整个 SVG 视口的像素,而不是仅应用滤镜的那个元素。通过明确设置 x/y/width/height,可减少 50%~80% 的像素处理量。
7.3 避免动画 stdDeviation
动态修改 feGaussianBlur 的 stdDeviation 会强制浏览器在每一帧重新计算模糊矩阵,代价极大。如果需要”脉动发光“效果,更好的做法是预渲染一个静态模糊层,再用 CSS 动画控制 opacity 或 transform: scale()。
7.4 性能开销对照表
滤镜基元 | 性能开销 | 优化建议 |
|---|---|---|
feColorMatrix | 低 | 随意使用,开销很小 |
feMerge / feOffset | 低 | 轻量操作,可放心使用 |
feGaussianBlur | 中 | stdDev 不超过 8,不动画 |
feDropShadow | 中 | 优先用 CSS drop-shadow() |
feTurbulence | 高 | numOctaves≤3,限制区域 |
feDisplacementMap | 高 | 配合限制区域使用 |
7.5 其他实用建议
颜色空间:非必要时用 color-interpolation-filters="sRGB",减少线性 RGB 转换开销。
合并顺序:把模糊等重资源操作放在链路尽可能晚的位置,先处理小区域再合成。
缓存静态滤镜:不变滤镜定义一次,多处引用,避免重复计算。
will-change 提示:对动画元素用 will-change: filter 提示浏览器预分配缓冲。
八、进阶技巧:从会用到用得好
8.1 双色调(Duotone)效果
双色调是当下流行的设计风格,可用 feColorMatrix 的 matrix 模式精确实现:
<!-- 把图像映射到蓝紫双色调 -->
<filter id="duotone">
<feColorMatrix type="matrix" values="
0.2 0.6 0.1 0 0.1
0.1 0.3 0.5 0 0.0
0.4 0.2 0.4 0 0.2
0 0 0 1 0"/>
</filter>原理是先通过矩阵第一行做灰度加权(R、G、B 通道按不同权重混合),再把灰度值映射到目标颜色空间。这种技术适用于平面设计、专辑封面、专题页面等场景。
8.2 模拟色觉障碍(无障碍设计)
前端环境已支持用 SVG 滤镜模拟色觉障碍(如红色盲 Deuteranopia)。通过精确的 feColorMatrix 矩阵,可以在页面顶层覆盖一层”滤镜”,实时预览不同色觉能力用户看到的效果。
<!-- 模拟绿色盲(Deuteranopia) -->
<svg style="position:fixed;width:0;height:0">
<filter id="deuteranopia">
<feColorMatrix values="
0.367 0.861 -0.228 0 0
0.280 0.673 0.047 0 0
-0.012 0.043 0.969 0 0
0 0 0 1 0"/>
</filter>
</svg>
<style>:root { filter: url(#deuteranopia); }</style>8.3 动态滤镜参数(JavaScript 控制)
用 JavaScript 动态修改滤镜属性,可以实现交互式效果:
// 让噪声「呼吸」——模拟水面流动
const turbulence = document.querySelector('feTurbulence');
let frame = 0;
function animate() {
frame++;
const freq = 0.04 + Math.sin(frame * 0.01) * 0.02;
turbulence.setAttribute('baseFrequency', freq);
requestAnimationFrame(animate);
}
animate();性能提示:动画时把幅度控制在较小范围(如 ±0.02),不要让 baseFrequency 大幅变化。幅度太大会让重绘开销暴增,容易卡顿。
九、常见场景速查表
想要的效果 | 用什么基元组合 | 备注 |
|---|---|---|
投影 | feGaussianBlur + feOffset + feMerge | 或用 feDropShadow 替代 |
发光 | feGaussianBlur + feMerge | 可加 feFood 着色 |
黑白/复古 | feColorMatrix type="saturate" values="0" | matrix 模式更灵活 |
毛玻璃 | feGaussianBlur(配合背景) | CSS backdrop-filter 更优 |
水波纹/扭曲 | feTurbulence + feDisplacementMap | 注意性能开销 |
云朵/纹理 | feTurbulence(单独使用或配合着色) | fractalNoise 更平滑 |
颜色替换 | feColorMatrix type="matrix" | 需计算 4 × 5 矩阵 |
内阴影 | feOffset + feComposite operator="in" | 高级技巧,需多步链路 |
十、总结
知识点 | 一句话总结 |
|---|---|
<filter> | 镜的容器,用 id 标识,放在 <defs> 中 |
滤镜基元 | 每个基元负责一种具体处理(模糊、偏移、颜色变换等) |
in / result | 基元的输入输出,用于串联多个基元 |
feGaussianBlur | 高斯模糊,制作阴影和发光的基础 |
feOffset | 位移,控制阴影的方向和距离 |
feMerge | 图层叠加,把多个结果合成一张图 |
feColorMatrix | 颜色矩阵,实现黑白、色相旋转等 |
feTurbulence | 噪声生成,制作云、水、纹理等自然效果 |
feDisplacementMap | 位移映射,实现扭曲和波纹 |
滤镜边界 | 记得扩大 x/y/width/height,防止效果被裁剪 |
性能策略 | 能用 CSS 滤镜的优先 CSS;SVG 留给 CSS 做不到的效果 |
核心心法:
SVG 滤镜的本质是图像处理流水线。你把原始图形送进流水线,经过一道道“工序”(滤镜基元),每一道工序都在修改像素的颜色或位置,最后输出成品。
掌握这个“流水线思维”,你就能把任何复杂的视觉效果拆解成一系列可组合的步骤——先用 feTurbulence 生成噪声,再用 feDisplacementMap 扭曲,再用 feColorMatrix 调色,最后用 feMerge 合成…… 就像在代码里用 Photoshop 一样。