前置知识: SVG

SVG 路径 path 详解

5 minIntermediate2026/7/18

path 命令、贝塞尔曲线、弧线、相对坐标与复杂路径绘制技巧。

1. path 概述

<path> 是 SVG 中最强大的元素,通过 d 属性的命令序列描述任意形状。所有基本形都可用 path 表达。

<svg viewBox="0 0 200 100">
  <path d="M 10 10 L 190 10 L 190 90 L 10 90 Z" fill="#4f5bd5" />
</svg>

2. 命令总览

命令含义参数大小写区别
M移动到(moveTo)x,y大写绝对,小写相对
L直线到(lineTo)x,y同上
H水平线x同上
V垂直线y同上
C三次贝塞尔x1,y1 x2,y2 x,y同上
S平滑三次贝塞尔x2,y2 x,y同上
Q二次贝塞尔x1,y1 x,y同上
T平滑二次贝塞尔x,y同上
A弧线rx,ry rot large,sweep x,y同上
Z闭合路径大小写等价

绝对坐标:以坐标系原点为参考;相对坐标:以前一命令终点为参考。

3. 直线命令

3.1 M / L

<path d="M 10 10 L 100 10 L 100 50 L 10 50 Z" fill="#4f5bd5" />

绘制矩形:从 (10,10) → (100,10) → (100,50) → (10,50) → 闭合回起点。

3.2 H / V

<path d="M 10 10 H 100 V 50 H 10 Z" fill="#00b894" />

H 100 等价于 L 100 当前yV 50 等价于 L 当前x 50

3.3 相对坐标

<!-- 绝对 -->
<path d="M 10 10 L 100 10 L 100 50" />
<!-- 相对:等价效果 -->
<path d="M 10 10 l 90 0 l 0 40" />

相对命令 l 90 0 表示从前一点向右移动 90,y 不变。

4. 贝塞尔曲线

4.1 二次贝塞尔 Q

Q x1,y1 x,y:一个控制点 + 终点。

<svg viewBox="0 0 200 100">
  <!-- 控制点 (100,10),终点 (190,90) -->
  <path d="M 10 90 Q 100 10 190 90" fill="none" stroke="#4f5bd5" stroke-width="3" />
  <!-- 辅助线 -->
  <line x1="10" y1="90" x2="100" y2="10" stroke="#ccc" stroke-dasharray="3" />
  <line x1="100" y1="10" x2="190" y2="90" stroke="#ccc" stroke-dasharray="3" />
</svg>

4.2 平滑二次贝塞尔 T

T x,y:自动反射前一控制点,形成连续平滑曲线。

<path d="M 10 90 Q 100 10 190 90 T 370 90" fill="none" stroke="#d63031" stroke-width="3" />

第二个控制点自动为 (280, 170),形成波浪。

4.3 三次贝塞尔 C

C x1,y1 x2,y2 x,y:两个控制点 + 终点,可表达更复杂曲线。

<svg viewBox="0 0 200 100">
  <path d="M 10 50 C 50 10 150 90 190 50" fill="none" stroke="#00b894" stroke-width="3" />
</svg>

4.4 平滑三次贝塞尔 S

S x2,y2 x,y:第二控制点自动反射,第一控制点需显式提供。

<path d="M 10 50 C 50 10 100 90 150 50 S 250 10 290 50" fill="none" stroke="#d63031" />

5. 弧线命令 A

A rx,ry x-axis-rotation large-arc-flag sweep-flag x,y

参数含义
rx,ry椭圆半径
x-axis-rotation椭圆 x 轴旋转角度
large-arc-flag0 短弧 / 1 长弧
sweep-flag0 逆时针 / 1 顺时针
x,y终点

5.1 四种弧组合

<svg viewBox="0 0 400 200">
  <!-- 从 (50,100) 到 (150,100),半径 50 -->
  <path d="M 50 100 A 50 50 0 0 0 150 100" fill="none" stroke="#4f5bd5" />
  <path d="M 250 100 A 50 50 0 0 1 350 100" fill="none" stroke="#00b894" />
  <path d="M 50 50 A 50 50 0 1 0 150 50" fill="none" stroke="#d63031" />
  <path d="M 250 50 A 50 50 0 1 1 350 50" fill="none" stroke="#f9a825" />
</svg>

5.2 圆弧扇形

<svg viewBox="0 0 200 200">
  <path d="M 100 100 L 100 20 A 80 80 0 0 1 180 100 Z" fill="#4f5bd5" />
</svg>

绘制 1/4 扇形:从圆心 (100,100) → (100,20) → 顺时针弧到 (180,100) → 闭合。

6. 闭合路径 Z

Z(或 z)从当前点连回 M 起点形成闭合。

<!-- 不闭合:不画最后一条边 -->
<path d="M 10 10 L 100 10 L 100 50" fill="none" stroke="#000" />
<!-- 闭合:自动连接终点到起点 -->
<path d="M 10 10 L 100 10 L 100 50 Z" fill="#4f5bd5" />

闭合后 fill 才能正确填充内部。

7. 路径填充规则 fill-rule

复杂路径(自相交或多子路径)的填充行为由 fill-rule 控制。

7.1 nonzero(默认)

<path
  d="M 10 10 L 190 10 L 190 90 L 10 90 Z M 50 30 L 150 30 L 150 70 L 50 70 Z"
  fill="#4f5bd5"
  fill-rule="nonzero"
/>

外矩形 + 内矩形:nonzero 规则下内矩形被”挖空”(外顺时针 + 内逆时针 → 区域计数为 0)。

7.2 evenodd

<path
  d="M 10 10 L 190 10 L 190 90 L 10 90 Z M 50 30 L 150 30 L 150 70 L 50 70 Z"
  fill="#00b894"
  fill-rule="evenodd"
/>

evenodd 规则下,无论方向,奇数次穿越绘制,偶数次不绘制 → 形成环带效果。

7.3 五角星示例

<!-- nonzero:中心填充 -->
<path
  d="M 100 10 L 120 70 L 180 70 L 130 105 L 150 165 L 100 130 L 50 165 L 70 105 L 20 70 L 80 70 Z"
  fill="#d63031"
  fill-rule="nonzero"
/>

<!-- evenodd:中心镂空 -->
<path
  d="M 100 10 L 120 70 L 180 70 L 130 105 L 150 165 L 100 130 L 50 165 L 70 105 L 20 70 L 80 70 Z"
  fill="#f9a825"
  fill-rule="evenodd"
/>

8. 多子路径

单个 <path> 可包含多个 M 命令,形成多个独立子路径。

<!-- 两个独立三角形 -->
<path d="M 10 10 L 90 10 L 50 90 Z M 110 10 L 190 10 L 150 90 Z" fill="#4f5bd5" />

9. 路径长度与测量

pathLength 属性将路径归一化到指定长度,便于 stroke-dasharray 动画。

<path
  d="M 10 50 Q 100 10 190 50"
  fill="none"
  stroke="#4f5bd5"
  stroke-width="3"
  pathLength="100"
  stroke-dasharray="50 50"
/>
<!-- pathLength=100,dasharray 50 50 表示画一半留一半 -->

JavaScript 获取实际长度:

const path = document.querySelector('path');
const length = path.getTotalLength();
console.log(length); // 例如 200
const point = path.getPointAtLength(100); // 路径中点坐标

10. 实战:手写心形

<svg viewBox="0 0 100 100" width="200" height="200">
  <path
    d="M 50 30
       C 30 10 0 20 0 50
       C 0 70 30 90 50 100
       C 70 90 100 70 100 50
       C 100 20 70 10 50 30 Z"
    fill="#d63031"
  />
</svg>

解析

  • 起点 (50,30):心形顶部凹陷
  • C 到 (0,50):左半弧
  • C 到 (50,100):底部尖角
  • C 到 (100,50):右半弧
  • C 回 (50,30):闭合

11. 路径优化技巧

技巧说明
使用相对坐标小写命令减少数字位数,文件更小
合并连续命令多个 L 可省略命令字母:L 10 10 20 20 30 30
使用 H/V水平垂直线用 H/V 比 L 更短
复用路径复杂路径用 <defs> + <use>
SVGO 压缩工具自动优化坐标精度与冗余

下一篇介绍 SVG 文本,包括 <text><tspan><textPath> 等排版能力。