SVG深度解析:从基础原理到高级应用

6 阅读4分钟

1. SVG基础概念与核心优势

什么是SVG?

SVG(Scalable Vector Graphics)是一种基于XML的矢量图像格式,由W3C联盟制定标准。与基于像素的位图格式(如JPEG、PNG)不同,SVG使用数学公式描述图形,通过点、线、曲线和形状来构建图像。

SVG的核心优势

无限缩放能力

<svg viewBox="0 0 100 100">
  <circle cx="50" cy="50" r="40" fill="red"/>
</svg>

这个简单的圆形SVG可以放大到任意尺寸而不失真,因为浏览器会根据数学公式重新计算绘制。

文件体积优化 对于几何图形、图标和简单插图,SVG文件通常比同等质量的位图小得多。复杂的SVG可以通过优化工具进一步减小体积。

完整的可编程性 SVG DOM完全暴露给JavaScript,允许动态修改和交互:

const circle = document.querySelector('circle');
circle.addEventListener('click', () => {
  circle.setAttribute('fill', 'blue');
});

卓越的可访问性 SVG文本内容可以被搜索引擎索引,屏幕阅读器可以读取,支持国际化:

<svg role="img" aria-labelledby="title desc">
  <title id="title">绿色圆形</title>
  <desc id="desc">一个半径为40像素的绿色圆形</desc>
  <circle cx="50" cy="50" r="40" fill="green"/>
</svg>

2. SVG视图框与坐标系统

viewBox的魔力

viewBox属性定义了SVG内容的坐标系和纵横比:

<svg width="200" height="100" viewBox="0 0 100 100">
  <!-- 内容 -->
</svg>

viewBox的四个参数分别是:min-x, min-y, width, height。这个强大的特性使得SVG可以自适应不同容器尺寸。

保持纵横比

preserveAspectRatio属性控制viewBox如何适应视口:

<svg preserveAspectRatio="xMidYMid meet">
  <!-- 内容将居中显示并保持比例 -->
</svg>

3. SVG基本形状元素详解

基本形状元素

SVG提供了一系列预定义的基本形状元素:

矩形 (rect)

<rect x="10" y="10" width="80" height="60" rx="10" ry="10"/>
  • x, y: 左上角坐标
  • width, height: 宽度和高度
  • rx, ry: 圆角半径

圆形 (circle)

<circle cx="50" cy="50" r="40"/>
  • cx, cy: 圆心坐标
  • r: 半径

椭圆 (ellipse)

<ellipse cx="50" cy="50" rx="40" ry="30"/>
  • cx, cy: 中心点坐标
  • rx, ry: x轴和y轴半径

直线 (line)

<line x1="10" y1="10" x2="90" y2="90" stroke="black"/>
  • x1, y1: 起点坐标
  • x2, y2: 终点坐标

折线 (polyline)

<polyline points="10,10 50,90 90,10" fill="none" stroke="black"/>

多边形 (polygon)

<polygon points="50,10 90,90 10,90" fill="red"/>

多边形会自动闭合路径,而折线不会。

4. 路径(Path)元素:SVG的终极武器

路径命令详解

路径是SVG中最强大、最灵活的元素,使用一系列命令描述形状:

移动命令 (M/m)

<path d="M10,10"/> <!-- 移动到绝对坐标(10,10) -->
<path d="m10,10"/> <!-- 相对于当前位置移动(10,10) -->

直线命令 (L/l, H/h, V/v)

<path d="M10,10 L90,10"/> <!-- 画直线到(90,10) -->
<path d="M10,10 H90"/>    <!-- 水平线到x=90 -->
<path d="M10,10 V90"/>    <!-- 垂直线到y=90 -->

三次贝塞尔曲线 (C/c, S/s) 三次贝塞尔曲线需要两个控制点:

<path d="M10,80 C40,10 60,10 90,80" stroke="black" fill="none"/>
  • S命令用于创建平滑连接的曲线

二次贝塞尔曲线 (Q/q, T/t) 二次贝塞尔曲线只需要一个控制点:

<path d="M10,80 Q50,10 90,80" stroke="black" fill="none"/>
  • T命令用于创建平滑连接的二次曲线

椭圆弧 (A/a) 椭圆弧命令是最复杂的路径命令:

<path d="M10,50 A40,40 0 0,1 90,50" stroke="black" fill="none"/>

参数:rx, ry, x-axis-rotation, large-arc-flag, sweep-flag, x, y

闭合路径 (Z/z)

<path d="M10,10 L90,10 L50,90 Z"/> <!-- 三角形 -->

5. SVG文本与样式系统

文本渲染

SVG提供了强大的文本控制能力:

<text x="50" y="50" text-anchor="middle" font-family="Arial" font-size="20">
  可样式化的文本
</text>

文本路径

文本可以沿着任意路径排列:

<defs>
  <path id="text-curve" d="M10,90 Q50,10 90,90"/>
</defs>
<text>
  <textPath href="#text-curve">弯曲的文本效果</textPath>
</text>

CSS样式应用

SVG元素可以使用CSS进行样式控制:

circle {
  fill: red;
  stroke: blue;
  stroke-width: 3;
  transition: fill 0.3s ease;
}

circle:hover {
  fill: orange;
}

6. SVG渐变与图案

线性渐变

<defs>
  <linearGradient id="myGradient" x1="0%" y1="0%" x2="100%" y2="0%">
    <stop offset="0%" stop-color="red"/>
    <stop offset="100%" stop-color="blue"/>
  </linearGradient>
</defs>
<rect x="10" y="10" width="80" height="80" fill="url(#myGradient)"/>

径向渐变

<defs>
  <radialGradient id="radialGrad" cx="50%" cy="50%" r="50%">
    <stop offset="0%" stop-color="white"/>
    <stop offset="100%" stop-color="black"/>
  </radialGradient>
</defs>
<circle cx="50" cy="50" r="40" fill="url(#radialGrad)"/>

图案填充

<defs>
  <pattern id="pattern" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse">
    <circle cx="10" cy="10" r="5" fill="red"/>
  </pattern>
</defs>
<rect width="100" height="100" fill="url(#pattern)"/>

7. SVG滤镜效果

高斯模糊

<defs>
  <filter id="blur">
    <feGaussianBlur in="SourceGraphic" stdDeviation="5"/>
  </filter>
</defs>
<circle cx="50" cy="50" r="40" filter="url(#blur)"/>

发光效果

<defs>
  <filter id="glow" x="-50%" y="-50%" width="200%" height="200%">
    <feGaussianBlur in="SourceGraphic" stdDeviation="5" result="blur"/>
    <feMerge>
      <feMergeNode in="blur"/>
      <feMergeNode in="SourceGraphic"/>
    </feMerge>
  </filter>
</defs>

颜色矩阵

<filter id="saturate">
  <feColorMatrix type="saturate" values="0.5"/>
</filter>

8. SVG动画技术

SMIL动画(原生SVG动画)

<circle cx="50" cy="50" r="20" fill="red">
  <animate attributeName="cx" from="50" to="150" dur="2s" repeatCount="indefinite"/>
</circle>

CSS动画

@keyframes move {
  from { transform: translateX(0); }
  to { transform: translateX(100px); }
}

circle {
  animation: move 2s infinite alternate;
}

JavaScript动画

function animateSVG() {
  const element = document.getElementById('animated');
  let position = 0;
  
  function update() {
    position = (position + 1) % 100;
    element.setAttribute('cx', position);
    requestAnimationFrame(update);
  }
  
  update();
}

GreenSock (GSAP) 动画库

gsap.to("#myElement", {
  duration: 2,
  x: 100,
  rotation: 360,
  ease: "bounce.out"
});

9. SVG剪辑与蒙版

剪辑路径 (clipPath)

<defs>
  <clipPath id="circleClip">
    <circle cx="50" cy="50" r="40"/>
  </clipPath>
</defs>
<rect x="10" y="10" width="80" height="80" clip-path="url(#circleClip)"/>

蒙版 (mask)

<defs>
  <mask id="fadeMask">
    <linearGradient id="gradient" x1="0%" y1="0%" x2="100%" y2="0%">
      <stop offset="0%" stop-color="white"/>
      <stop offset="100%" stop-color="black"/>
    </linearGradient>
    <rect x="0" y="0" width="100" height="100" fill="url(#gradient)"/>
  </mask>
</defs>
<rect x="0" y="0" width="100" height="100" fill="blue" mask="url(#fadeMask)"/>

10. 高级SVG技术

响应式SVG

<svg viewBox="0 0 100 100" preserveAspectRatio="xMidYMid meet">
  <!-- 内容会自动适应容器大小 -->
</svg>

SVG符号系统

<defs>
  <symbol id="icon" viewBox="0 0 24 24">
    <path d="M12 2L3 9v12h18V9l-9-7z"/>
  </symbol>
</defs>

<svg class="icon"><use href="#icon"/></svg>
<svg class="icon" width="32" height="32"><use href="#icon"/></svg>

优化与性能

  • 使用SVGO等工具优化SVG文件
  • 减少路径节点的数量
  • 合理使用分组(g元素)
  • 避免不必要的滤镜效果

结语

SVG作为一种强大的矢量图形格式,在现代Web开发中发挥着越来越重要的作用。从简单的图标到复杂的数据可视化,从静态图形到交互动画,SVG都能提供出色的解决方案。掌握SVG不仅意味着掌握了一种图像格式,更是打开了创造丰富、可扩展、高性能Web体验的大门。