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
| SVG | Canvas | |
|---|---|---|
| 渲染方式 | 矢量(数学描述) | 像素(位图) |
| 缩放 | 无损 | 会模糊 |
| DOM | 每个图形都是 DOM 元素 | 单元素,无独立子节点 |
| 交互 | 可为形状绑定事件 | 需手动计算坐标 |
| 性能(大量元素) | 差(DOM 节点多) | 好 |
| 性能(大面积) | 好 | 差 |
| 适用场景 | 图标、图表、UI | 游戏、图像处理、热图 |
简单决策:需要交互或缩放?用 SVG。需要大量像素操作或游戏渲染?用 Canvas。