HTML SVG

SVG(Scalable Vector Graphics,可缩放矢量图形)是一种基于 XML 的矢量图形格式。与 Canvas 不同,SVG 是声明式的——每个图形都是一个 DOM 元素。

内嵌 SVG

有三种方式在 HTML 中使用 SVG:

html
<!-- 方式一:直接内嵌(推荐,可 CSS/JS 控制) -->
<svg width="200" height="200" viewBox="0 0 200 200"
     xmlns="http://www.w3.org/2000/svg">
  <circle cx="100" cy="100" r="80" fill="#2563eb" />
</svg>

<!-- 方式二:img 标签(静态,不可 CSS/JS 控制) -->
<img src="icon.svg" alt="图标" width="48" height="48">

<!-- 方式三:CSS background -->
<div style="background: url(icon.svg); width: 48px; height: 48px;"></div>

直接内嵌 SVG 的优势:可以用 CSS 控制颜色、可以用 JavaScript 操作元素、支持交互动画。<img> 方式加载的 SVG 是静态的,无法单独控制内部元素。

基本形状

html
<svg width="400" height="300" viewBox="0 0 400 300">
  <!-- 矩形 -->
  <rect x="10" y="10" width="80" height="60"
        fill="#2563eb" stroke="#1e40af" stroke-width="2" rx="8" />

  <!-- 圆形 -->
  <circle cx="150" cy="40" r="30"
          fill="#22c55e" />

  <!-- 椭圆 -->
  <ellipse cx="240" cy="40" rx="40" ry="25"
           fill="#f59e0b" />

  <!-- 线段 -->
  <line x1="10" y1="100" x2="150" y2="140"
        stroke="#ef4444" stroke-width="3" />

  <!-- 折线 -->
  <polyline points="180,100 220,140 260,100 300,140"
            fill="none" stroke="#8b5cf6" stroke-width="3" />

  <!-- 多边形 -->
  <polygon points="350,140 370,100 390,140"
           fill="#ec4899" />
</svg>

<path> — 路径

<path> 是 SVG 中最强大的元素,通过 d 属性定义任意复杂形状:

html
<svg width="200" height="200" viewBox="0 0 200 200">
  <!-- 心形 -->
  <path d="M 100,180
           C 50,140 10,100 10,60
           A 30,30 0 0,1 70,30
           A 30,30 0 0,1 100,60
           A 30,30 0 0,1 130,30
           A 30,30 0 0,1 190,60
           C 190,100 150,140 100,180 Z"
        fill="#ef4444" />
</svg>

路径命令速查:

命令含义
M x,y移动到
L x,y画直线到
H x水平线到
V y垂直线到
C ...三次贝塞尔曲线
Q ...二次贝塞尔曲线
A ...弧线
Z闭合路径

SVG 文字

html
<svg width="400" height="100" viewBox="0 0 400 100">
  <text x="20" y="40"
        font-family="system-ui, sans-serif"
        font-size="28"
        font-weight="bold"
        fill="#1e293b">
    Hello SVG!
  </text>

  <!-- 沿路径排列 -->
  <path id="textPath" d="M 20,80 C 100,50 300,50 380,80"
        fill="none" stroke="#cbd5e1" />
  <text font-size="14" fill="#64748b">
    <textPath href="#textPath">
      文字沿着曲线路径排列
    </textPath>
  </text>
</svg>

渐变与滤镜

html
<svg width="400" height="200" viewBox="0 0 400 200">
  <defs>
    <!-- 线性渐变 -->
    <linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="100%">
      <stop offset="0%" stop-color="#2563eb" />
      <stop offset="100%" stop-color="#22c55e" />
    </linearGradient>

    <!-- 阴影滤镜 -->
    <filter id="shadow">
      <feDropShadow dx="2" dy="2" stdDeviation="3" flood-opacity="0.3" />
    </filter>
  </defs>

  <rect x="20" y="20" width="160" height="100"
        fill="url(#grad1)" rx="8" filter="url(#shadow)" />

  <circle cx="270" cy="70" r="50"
          fill="url(#grad1)" filter="url(#shadow)" />
</svg>

SVG vs Canvas

SVGCanvas
渲染方式矢量(数学描述)像素(位图)
缩放无损会模糊
DOM每个图形都是 DOM 元素单元素,无独立子节点
交互可为形状绑定事件需手动计算坐标
性能(大量元素)差(DOM 节点多)
性能(大面积)
适用场景图标、图表、UI游戏、图像处理、热图

简单决策:需要交互或缩放?用 SVG。需要大量像素操作或游戏渲染?用 Canvas。