SVG 滤镜简介
SVG 滤镜(Filters)可以为图形添加各种视觉效果,如模糊、阴影、颜色变换等。
基本结构
滤镜定义在 <defs> 元素中,通过 filter 属性应用:
html
<svg width="200" height="100">
<defs>
<filter id="myFilter">
<!-- 滤镜效果定义 -->
</filter>
</defs>
<rect filter="url(#myFilter)" ... />
</svg>滤镜元素
| 滤镜 | 描述 |
|---|---|
feGaussianBlur | 高斯模糊 |
feOffset | 偏移 |
feBlend | 混合 |
feColorMatrix | 颜色矩阵变换 |
feComponentTransfer | 分量转换 |
feComposite | 组合 |
feConvolveMatrix | 卷积矩阵 |
feDiffuseLighting | 漫反射光照 |
feDisplacementMap | 位移映射 |
feFlood | 填充 |
feMerge | 合并 |
feMorphology | 形态学操作 |
feSpecularLighting | 镜面反射光照 |
feTurbulence | 湍流噪声 |
feDropShadow | 阴影(简化版) |
简单模糊效果
html
<svg width="300" height="120">
<defs>
<filter id="blur1">
<feGaussianBlur stdDeviation="2"/>
</filter>
<filter id="blur2">
<feGaussianBlur stdDeviation="5"/>
</filter>
</defs>
<!-- 无滤镜 -->
<rect x="20" y="20" width="60" height="60" fill="#3b82f6"/>
<text x="50" y="100" text-anchor="middle" font-size="12">原图</text>
<!-- 轻微模糊 -->
<rect x="120" y="20" width="60" height="60" fill="#3b82f6" filter="url(#blur1)"/>
<text x="150" y="100" text-anchor="middle" font-size="12">轻微模糊</text>
<!-- 强模糊 -->
<rect x="220" y="20" width="60" height="60" fill="#3b82f6" filter="url(#blur2)"/>
<text x="250" y="100" text-anchor="middle" font-size="12">强模糊</text>
</svg>阴影效果
html
<svg width="300" height="120">
<defs>
<filter id="shadow1" x="-20%" y="-20%" width="140%" height="140%">
<feDropShadow dx="3" dy="3" stdDeviation="3" flood-color="#00000040"/>
</filter>
</defs>
<rect x="30" y="20" width="80" height="60" rx="8" fill="#3b82f6" filter="url(#shadow1)"/>
<circle cx="200" cy="50" r="35" fill="#22c55e" filter="url(#shadow1)"/>
</svg>颜色滤镜
灰度效果
html
<svg width="300" height="120">
<defs>
<filter id="grayscale">
<feColorMatrix type="saturate" values="0"/>
</filter>
</defs>
<!-- 原图 -->
<circle cx="60" cy="60" r="40" fill="#3b82f6"/>
<text x="60" y="115" text-anchor="middle" font-size="12">原图</text>
<!-- 灰度 -->
<circle cx="180" cy="60" r="40" fill="#3b82f6" filter="url(#grayscale)"/>
<text x="180" y="115" text-anchor="middle" font-size="12">灰度</text>
</svg>色相旋转
html
<svg width="400" height="120">
<defs>
<filter id="hue90">
<feColorMatrix type="hueRotate" values="90"/>
</filter>
<filter id="hue180">
<feColorMatrix type="hueRotate" values="180"/>
</filter>
<filter id="hue270">
<feColorMatrix type="hueRotate" values="270"/>
</filter>
</defs>
<circle cx="50" cy="50" r="35" fill="#3b82f6"/>
<text x="50" y="100" text-anchor="middle" font-size="11">0°</text>
<circle cx="130" cy="50" r="35" fill="#3b82f6" filter="url(#hue90)"/>
<text x="130" y="100" text-anchor="middle" font-size="11">90°</text>
<circle cx="210" cy="50" r="35" fill="#3b82f6" filter="url(#hue180)"/>
<text x="210" y="100" text-anchor="middle" font-size="11">180°</text>
<circle cx="290" cy="50" r="35" fill="#3b82f6" filter="url(#hue270)"/>
<text x="290" y="100" text-anchor="middle" font-size="11">270°</text>
</svg>组合滤镜
可以组合多个滤镜效果:
html
<svg width="300" height="150">
<defs>
<filter id="combined" x="-20%" y="-20%" width="140%" height="140%">
<!-- 阴影 -->
<feGaussianBlur in="SourceAlpha" stdDeviation="4" result="blur"/>
<feOffset in="blur" dx="4" dy="4" result="offsetBlur"/>
<!-- 合并原图和阴影 -->
<feMerge>
<feMergeNode in="offsetBlur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<rect x="30" y="30" width="100" height="70" rx="10" fill="#3b82f6" filter="url(#combined)"/>
<text x="180" y="70" font-size="28" font-weight="bold" fill="#ef4444" filter="url(#combined)">SVG</text>
</svg>filter 属性详解
filterUnits
定义滤镜坐标系统:
html
<filter id="f1" filterUnits="userSpaceOnUse">
<!-- 使用用户坐标系统 -->
</filter>
<filter id="f2" filterUnits="objectBoundingBox">
<!-- 使用对象边界框(默认) -->
</filter>x, y, width, height
定义滤镜区域:
html
<filter id="myFilter" x="-50%" y="-50%" width="200%" height="200%">
<!-- 滤镜效果可能超出对象边界,需要扩大区域 -->
</filter>滤镜输入输出
使用 in 和 result 属性连接滤镜效果:
html
<filter id="chainedFilter">
<!-- 第一步:模糊 -->
<feGaussianBlur in="SourceGraphic" stdDeviation="2" result="blur"/>
<!-- 第二步:偏移模糊结果 -->
<feOffset in="blur" dx="5" dy="5" result="offsetBlur"/>
<!-- 第三步:与原图混合 -->
<feBlend in="SourceGraphic" in2="offsetBlur" mode="normal"/>
</filter>预定义输入
| 值 | 描述 |
|---|---|
SourceGraphic | 原始图形 |
SourceAlpha | 原始图形的 alpha 通道 |
BackgroundImage | 背景图像 |
BackgroundAlpha | 背景的 alpha 通道 |
FillPaint | 填充颜色 |
StrokePaint | 描边颜色 |
实际应用示例
发光效果
html
<svg width="200" height="100">
<defs>
<filter id="glow" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur stdDeviation="4" result="blur"/>
<feMerge>
<feMergeNode in="blur"/>
<feMergeNode in="blur"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<text x="100" y="60" text-anchor="middle" font-size="32" font-weight="bold"
fill="#fbbf24" filter="url(#glow)">GLOW</text>
</svg>内阴影效果
html
<svg width="200" height="100">
<defs>
<filter id="innerShadow">
<feOffset dx="2" dy="2"/>
<feGaussianBlur stdDeviation="2" result="offset-blur"/>
<feComposite operator="out" in="SourceGraphic" in2="offset-blur" result="inverse"/>
<feFlood flood-color="black" flood-opacity="0.4" result="color"/>
<feComposite operator="in" in="color" in2="inverse" result="shadow"/>
<feComposite operator="over" in="shadow" in2="SourceGraphic"/>
</filter>
</defs>
<rect x="30" y="20" width="140" height="60" rx="10" fill="#e5e7eb" filter="url(#innerShadow)"/>
</svg>噪点纹理
html
<svg width="200" height="100">
<defs>
<filter id="noise">
<feTurbulence type="fractalNoise" baseFrequency="0.8" numOctaves="4" result="noise"/>
<feBlend in="SourceGraphic" in2="noise" mode="multiply"/>
</filter>
</defs>
<rect x="10" y="10" width="180" height="80" fill="#3b82f6" filter="url(#noise)"/>
</svg>性能注意事项
性能提示
- 复杂滤镜会影响渲染性能
- 避免在大量元素上使用滤镜
- 考虑使用 CSS 滤镜替代简单效果
- 在动画中谨慎使用滤镜
下一步
了解了滤镜基础后,接下来深入学习 SVG 模糊效果!