SVG 技术解析

探索矢量图形的无限可能。从基础几何到复杂的交互动画,全方位掌握现代 Web 图形的核心技术。

01. 概念与原理

什么是 SVG?

SVG (Scalable Vector Graphics) 是一种基于 XML 的矢量图形格式。与传统的位图(如 PNG, JPG)不同,SVG 使用数学描述来定义图形。

核心特性:

  • 分辨率无关: 无论放大多少倍,边缘始终平滑清晰。
  • 可缩放: 完美适配各种屏幕尺寸和高像素密度显示器。
  • DOM 集成: 每一个 SVG 元素都是 DOM 的一部分,可以通过 CSS 和 JS 直接控制。
<!-- 一个简单的 SVG 结构 --> <svg width="200" height="200" xmlns="http://www.w3.org/2000/svg"> <circle cx="100" cy="100" r="80" fill="#00f2ff" /> </svg>
SVG 基础渲染演示

02. 核心图形元素

几何之美

SVG 提供了一系列预定义的形状元素,通过简单的属性即可构建复杂图形。

常用元素:

  • <rect>: 矩形。关键属性:x, y, width, height, rx, ry
  • <circle>: 圆形。关键属性:cx, cy, r
  • <ellipse>: 椭圆。关键属性:cx, cy, rx, ry
  • <line>: 直线。关键属性:x1, y1, x2, y2
  • <polyline>: 多段线。关键属性:points
  • <polygon>: 多边形。关键属性:points
<!-- 绘制一个带圆角的矩形 --> <rect x="10" y="10" width="100" height="60" rx="10" fill="none" stroke="#00f2ff" stroke-width="2" /> <!-- 绘制一个椭圆 --> <ellipse cx="60" cy="100" rx="50" ry="30" fill="#7000ff" /> <!-- 绘制多边形 --> <polygon points="100,10 40,198 190,78 10,78 160,198" fill="none" stroke="#ff00c8" />
基础几何元素组合

03. 路径详解

最强大的 SVG 元素

<path> 是 SVG 中最灵活和强大的元素,可以绘制几乎任何形状。它通过 d 属性定义路径数据。

路径命令:

  • M x y: 移动到某点(Move to)
  • L x y: 绘制直线到某点(Line to)
  • H x: 水平线(Horizontal line)
  • V y: 垂直线(Vertical line)
  • C x1 y1, x2 y2, x y: 三次贝塞尔曲线(Cubic Bezier)
  • Q x1 y1, x y: 二次贝塞尔曲线(Quadratic Bezier)
  • A rx ry rotation large-arc sweep x y: 圆弧(Arc)
  • Z: 闭合路径(Close path)

注:大写命令使用绝对坐标,小写命令使用相对坐标。

<!-- 绘制一个心形 --> <path d="M 150,100 C 150,80 130,60 110,60 C 90,60 70,80 70,100 C 70,130 150,180 150,180 C 150,180 230,130 230,100 C 230,80 210,60 190,60 C 170,60 150,80 150,100 Z" fill="#ff00c8" /> <!-- 绘制波浪曲线 --> <path d="M 0,150 Q 50,100 100,150 T 200,150" fill="none" stroke="#00f2ff" stroke-width="3" />
路径命令综合演示

04. 文本元素

SVG 中的文字艺术

SVG 支持强大的文本渲染功能,与 HTML 文本不同,SVG 文本是图形元素,可以应用所有 SVG 特性。

核心元素:

  • <text>: 基础文本元素。关键属性:x, y, font-size, fill
  • <tspan>: 文本分段,允许在 <text> 内部对不同部分应用不同样式。
  • <textPath>: 沿路径排列文本,创建曲线文字效果。

重要属性:

  • text-anchor: 文本对齐方式 (start, middle, end)。
  • dominant-baseline: 基线对齐 (middle, hanging, etc.)。
  • dx, dy: 相对偏移量。
  • rotate: 文字旋转角度。
  • lengthAdjust: 文本长度调整方式。
<!-- 基础文本 --> <text x="50" y="50" font-size="24" fill="#00f2ff"> Hello SVG! </text> <!-- 分段样式 --> <text x="50" y="100" font-size="20"> <tspan fill="cyan">Scalable</tspan> <tspan fill="magenta" font-weight="bold"> Vector</tspan> <tspan fill="yellow"> Graphics</tspan> </text> <!-- 沿路径文本 --> <defs> <path id="curve" d="M 50,150 Q 150,50 250,150" /> </defs> <text font-size="18" fill="#7000ff"> <textPath href="#curve"> 沿着曲线排列的文字 </textPath> </text>
SVG TEXT S c a l a b l e ✨ 沿着曲线排列 ✨ ◆ CIRCULAR TEXT LAYOUT ◆ SVG GRAPHICS ◆ SVG
文本元素综合演示

05. 样式与视觉表现

光影与质感

SVG 的样式可以通过属性直接定义,也可以通过 CSS 控制。它支持复杂的渐变和图案填充。

关键技术:

  • 填充与描边: fill, stroke, stroke-width
  • 渐变: <linearGradient><radialGradient>
  • 图案: <pattern> 用于创建重复的背景。
<defs> <linearGradient id="grad1"> <stop offset="0%" stop-color="cyan" /> <stop offset="100%" stop-color="blue" /> </linearGradient> </defs> <circle fill="url(#grad1)" ... />
渐变与图案填充演示

06. 坐标系统与变换

空间的艺术

理解 SVG 的坐标系是进阶的关键。默认坐标原点 (0,0) 位于左上角。

核心概念:

  • Viewport: SVG 的可视区域大小。
  • viewBox: 定义了 SVG 内部的坐标空间,实现“窗口”效果。
  • Transform: 改变元素的位置、角度和比例。
    • translate(x, y): 平移。
    • rotate(angle): 旋转。
    • scale(x, y): 缩放。
旋转变换 缩放 0.5
坐标系与 Transform 演示

07. 滤镜效果

光影与特效

SVG 滤镜可以创建各种视觉效果,如阴影、模糊、颜色调整等。滤镜在 <defs> 中定义,通过 filter 属性引用。

常用滤镜原语:

  • <feGaussianBlur>: 高斯模糊
  • <feDropShadow>: 投影阴影
  • <feColorMatrix>: 颜色矩阵变换
  • <feBlend>: 混合模式
  • <feOffset>: 偏移
  • <feMorphology>: 形态学操作(腐蚀/膨胀)
  • <feTurbulence>: 湍流噪声
<defs> <filter id="glow"> <feGaussianBlur stdDeviation="4" result="coloredBlur"/> <feMerge> <feMergeNode in="coloredBlur"/> <feMergeNode in="SourceGraphic"/> </feMerge> </filter> <filter id="shadow"> <feDropShadow dx="2" dy="2" stdDeviation="3" flood-color="#000" flood-opacity="0.5"/> </filter> </defs> <circle cx="100" cy="100" r="50" fill="#00f2ff" filter="url(#glow)" />
SVG
滤镜效果综合演示

08. 裁剪与蒙版

精确控制显示区域

裁剪和蒙版是控制 SVG 元素可见区域的两种方式。

核心概念:

  • 裁剪路径 (Clipping Path): 使用 <clipPath> 定义裁剪区域,只显示裁剪路径内的内容。是二值化的(全显示或全隐藏)。
  • 蒙版 (Mask): 使用 <mask> 定义透明度蒙版,支持渐变透明度。白色区域完全可见,黑色区域完全透明,灰色区域半透明。
<!-- 裁剪路径示例 --> <defs> <clipPath id="circleClip"> <circle cx="100" cy="100" r="50" /> </clipPath> </defs> <rect x="50" y="50" width="100" height="100" fill="blue" clip-path="url(#circleClip)" /> <!-- 蒙版示例 --> <defs> <mask id="fadeMask"> <rect x="0" y="0" width="200" height="200" fill="url(#gradient)" /> </mask> </defs> <rect x="0" y="0" width="200" height="200" fill="red" mask="url(#fadeMask)" />
SVG 渐变蒙版效果
裁剪与蒙版效果对比

09. 结构组织与复用

高效构建

SVG 提供了强大的复用机制,可以减少代码冗余并提高可维护性。

核心标签:

  • <g>: 分组。将多个元素组合在一起,统一应用样式或变换。
  • <defs>: 定义。存放不会直接显示的元素(如渐变、滤镜、模板)。
  • <use>: 实例化。引用 defs 中定义的模板。
<defs> <circle id="myDot" r="5" fill="cyan" /> </defs> <use href="#myDot" x="10" y="10" /> <use href="#myDot" x="50" y="10" />
使用 <defs> 和 <use> 实现组件复用

10. 动画与交互

赋予图形生命

SVG 不仅仅是静态的,它可以通过多种方式实现动态效果。

实现手段:

  • SMIL (原生动画): 使用 <animate>, <animateTransform> 等标签。
  • CSS 动画: 利用 @keyframes 控制 SVG 属性(如 stroke-dashoffset)。
  • JavaScript: 通过操控 DOM 属性实现复杂的交互逻辑。

现代 Web 开发中,CSS 动画和 JS 库(如 GSAP)是实现 SVG 动画的主流选择。

综合动画效果展示

11. 性能优化与最佳实践

高效使用 SVG

在大型项目中使用 SVG 时,性能优化至关重要。

优化建议:

  • 简化路径: 减少不必要的节点和控制点,使用工具如 SVGO 进行压缩。
  • 复用元素: 利用 <use> 复用元素,减少 DOM 节点数量。
  • 避免过度使用滤镜: 滤镜效果耗费性能,尤其是在移动设备上。
  • 使用 CSS 动画: CSS 动画通常比 SMIL 性能更好,并且兼容性更广。
  • viewBox 优化: 合理设置 viewBox 可以减少不必要的计算。
  • 延迟加载: 对非关键 SVG 进行延迟加载。
  • Sprite 技术: 将多个小图标合并为一个 SVG Sprite,减少 HTTP 请求。

最佳实践:

  • 使用语义化的 ID 和 class 名称
  • 保持 SVG 代码的可读性,适当添加注释
  • 使用 <title><desc> 提高可访问性
  • 考虑响应式设计,使用相对单位
  • 在生产环境中压缩 SVG 文件
<!-- 良好的 SVG 结构示例 --> <svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="icon-title"> <title id="icon-title">用户图标</title> <desc>一个代表用户的简单图标</desc> <defs> <!-- 复用定义 --> <circle id="head" cx="50" cy="30" r="15" /> </defs> <use href="#head" fill="#00f2ff" /> <path d="M 30 60 Q 50 80 70 60" fill="#00f2ff" /> </svg> <!-- 使用 CSS 动画 --> <style> .animated-icon { animation: pulse 2s infinite; } @keyframes pulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.1); } } </style>
✔ 使用 <use> 复用 - 9个实例,只有 1 个定义
高效复用与性能优化示例