路径
<path> 元素是 SVG 中最强大的绘图工具,可以绘制任何形状的图形。虽然基本形状元素能满足大部分需求,但路径提供了更精细的控制,是创建复杂图形的关键。
路径基础
<path> 元素通过 d 属性(data 的缩写)定义路径。d 属性包含一系列命令和参数,描述如何绘制图形。
<svg width="200" height="100" xmlns="http://www.w3.org/2000/svg">
<path d="M 10 10 L 190 10 L 190 90 L 10 90 Z"
fill="none" stroke="#3498db" stroke-width="2"/>
</svg>
每个命令由一个字母和一组参数组成。大写字母表示绝对坐标,小写字母表示相对坐标(相对于前一个点的位置)。
直线命令
移动命令 M
M 命令将画笔移动到指定位置,不绘制线条。通常用于设置路径的起点。
M x y (绝对坐标)
m dx dy (相对坐标)
<svg width="200" height="100" xmlns="http://www.w3.org/2000/svg">
<path d="M 50 50" stroke="#333" stroke-width="2"/>
<circle cx="50" cy="50" r="3" fill="#e74c3c"/>
<text x="60" y="55" font-size="12">起点 (50, 50)</text>
</svg>
单独使用 M 命令不会显示任何内容,它只是移动画笔位置。
直线命令 L
L 命令从当前位置画直线到指定位置。
L x y (绝对坐标)
l dx dy (相对坐标)
<svg width="200" height="100" xmlns="http://www.w3.org/2000/svg">
<path d="M 10 10 L 190 10 L 190 90 L 10 90"
fill="none" stroke="#2ecc71" stroke-width="2"/>
</svg>
这段代码画了一个开口的矩形:从 (10,10) 开始,依次画线到 (190,10)、(190,90)、(10,90)。
水平线命令 H
H 命令画水平线,只需要指定 x 坐标。
H x (绝对坐标)
h dx (相对坐标)
垂直线命令 V
V 命令画垂直线,只需要指定 y 坐标。
V y (绝对坐标)
v dy (相对坐标)
使用 H 和 V 绘制矩形
<svg width="200" height="100" xmlns="http://www.w3.org/2000/svg">
<path d="M 10 10 H 190 V 90 H 10 Z"
fill="none" stroke="#9b59b6" stroke-width="2"/>
</svg>
这比使用 L 命令更简洁:从 (10,10) 水平画到 x=190,垂直画到 y=90,水平画到 x=10,然后闭合。
闭合路径命令 Z
Z 命令从当前位置画直线到路径的起点,形成闭合图形。Z 命令不区分大小写。
Z 或 z
<svg width="200" height="100" xmlns="http://www.w3.org/2000/svg">
<path d="M 10 10 L 190 10 L 190 90 L 10 90 Z"
fill="#ecf0f1" stroke="#34495e" stroke-width="2"/>
</svg>
相对坐标示例
<svg width="200" height="100" xmlns="http://www.w3.org/2000/svg">
<path d="M 10 10 h 180 v 80 h -180 z"
fill="none" stroke="#e74c3c" stroke-width="2"/>
</svg>
使用相对坐标:从 (10,10) 向右移动 180,向下移动 80,向左移动 180,然后闭合。
曲线命令
曲线命令用于绘制平滑的曲线,包括贝塞尔曲线和弧线。
三次贝塞尔曲线 C
三次贝塞尔曲线需要两个控制点和一个终点,可以创建 S 形曲线。
C x1 y1, x2 y2, x y (绝对坐标)
c dx1 dy1, dx2 dy2, dx dy (相对坐标)
(x1, y1):起点的控制点,决定曲线起点的方向(x2, y2):终点的控制点,决定曲线终点的方向(x, y):曲线的终点
<svg width="300" height="150" xmlns="http://www.w3.org/2000/svg">
<path d="M 20 100 C 50 20, 150 20, 180 100"
fill="none" stroke="#3498db" stroke-width="2"/>
<circle cx="20" cy="100" r="3" fill="#e74c3c"/>
<circle cx="50" cy="20" r="3" fill="#95a5a6"/>
<circle cx="150" cy="20" r="3" fill="#95a5a6"/>
<circle cx="180" cy="100" r="3" fill="#e74c3c"/>
<line x1="20" y1="100" x2="50" y2="20" stroke="#bdc3c7" stroke-dasharray="3"/>
<line x1="180" y1="100" x2="150" y2="20" stroke="#bdc3c7" stroke-dasharray="3"/>
</svg>
控制点就像磁铁一样吸引曲线。曲线从起点出发,朝向第一个控制点方向,然后逐渐弯曲,最终从第二个控制点方向到达终点。
平滑三次贝塞尔曲线 S
当多条三次贝塞尔曲线连续时,可以使用 S 命令简化代码。S 命令会自动计算第一个控制点,使其与前一段曲线对称。
S x2 y2, x y (绝对坐标)
s dx2 dy2, dx dy (相对坐标)
<svg width="300" height="150" xmlns="http://www.w3.org/2000/svg">
<path d="M 20 100 C 50 20, 100 20, 130 100 S 210 180, 250 100"
fill="none" stroke="#2ecc71" stroke-width="2"/>
</svg>
S 命令的第一个控制点会自动设为前一个 C 或 S 命令第二个控制点的对称点,确保曲线平滑过渡。
二次贝塞尔曲线 Q
二次贝塞尔曲线只需要一个控制点,比三次贝塞尔曲线简单。
Q x1 y1, x y (绝对坐标)
q dx1 dy1, dx dy (相对坐标)
(x1, y1):控制点(x, y):终点
<svg width="200" height="150" xmlns="http://www.w3.org/2000/svg">
<path d="M 20 100 Q 100 20, 180 100"
fill="none" stroke="#9b59b6" stroke-width="2"/>
<circle cx="20" cy="100" r="3" fill="#e74c3c"/>
<circle cx="100" cy="20" r="3" fill="#95a5a6"/>
<circle cx="180" cy="100" r="3" fill="#e74c3c"/>
<line x1="20" y1="100" x2="100" y2="20" stroke="#bdc3c7" stroke-dasharray="3"/>
<line x1="180" y1="100" x2="100" y2="20" stroke="#bdc3c7" stroke-dasharray="3"/>
</svg>
平滑二次贝塞尔曲线 T
T 命令类似于 S 命令,自动计算控制点以保持曲线平滑。
T x y (绝对坐标)
t dx dy (相对坐标)
<svg width="250" height="150" xmlns="http://www.w3.org/2000/svg">
<path d="M 20 100 Q 60 20, 100 100 T 180 100"
fill="none" stroke="#e67e22" stroke-width="2"/>
</svg>
弧线命令 A
弧线命令可以绘制椭圆弧,是路径中最复杂的命令。
A rx ry x-axis-rotation large-arc-flag sweep-flag x y
a rx ry x-axis-rotation large-arc-flag sweep-flag dx dy
参数说明:
| 参数 | 说明 |
|---|---|
| rx, ry | 椭圆的 x 轴和 y 轴半径 |
| x-axis-rotation | 椭圆的旋转角度(度) |
| large-arc-flag | 0 表示小弧,1 表示大弧 |
| sweep-flag | 0 表示逆时针,1 表示顺时针 |
| x, y | 弧线终点 |
<svg width="300" height="200" xmlns="http://www.w3.org/2000/svg">
<path d="M 50 100 A 80 50 0 0 1 250 100"
fill="none" stroke="#1abc9c" stroke-width="2"/>
</svg>
这个例子绘制了一个椭圆弧:椭圆 x 半径 80,y 半径 50,无旋转,选择小弧,顺时针方向,从 (50,100) 到 (250,100)。
弧线的四种情况
给定相同的起点、终点和椭圆半径,可以画出四种不同的弧:
<svg width="300" height="200" xmlns="http://www.w3.org/2000/svg">
<path d="M 50 100 A 80 50 0 0 0 250 100" fill="none" stroke="#e74c3c" stroke-width="2"/>
<path d="M 50 100 A 80 50 0 0 1 250 100" fill="none" stroke="#3498db" stroke-width="2"/>
<path d="M 50 100 A 80 50 0 1 0 250 100" fill="none" stroke="#2ecc71" stroke-width="2"/>
<path d="M 50 100 A 80 50 0 1 1 250 100" fill="none" stroke="#9b59b6" stroke-width="2"/>
</svg>
- 红色:小弧,逆时针
- 蓝色:小弧,顺时针
- 绿色:大弧,逆时针
- 紫色:大弧,顺时针
路径填充规则
当路径自相交或包含多个子路径时,填充规则决定哪些区域被填充。
fill-rule: nonzero(默认)
非零环绕规则:从某点向任意方向发射射线,计算路径穿过射线的次数。顺时针穿过加 1,逆时针减 1,结果非零则填充。
<svg width="200" height="150" xmlns="http://www.w3.org/2000/svg">
<path d="M 100 10 L 190 140 L 10 140 Z
M 100 40 L 160 120 L 40 120 Z"
fill="#3498db" fill-rule="nonzero"/>
</svg>
fill-rule: evenodd
奇偶规则:射线穿过路径奇数次则填充,偶数次则不填充。
<svg width="200" height="150" xmlns="http://www.w3.org/2000/svg">
<path d="M 100 10 L 190 140 L 10 140 Z
M 100 40 L 160 120 L 40 120 Z"
fill="#e74c3c" fill-rule="evenodd"/>
</svg>
实用示例
绘制心形
<svg width="200" height="180" xmlns="http://www.w3.org/2000/svg">
<path d="M 100 160
C 100 160, 20 100, 20 60
C 20 20, 60 20, 100 60
C 140 20, 180 20, 180 60
C 180 100, 100 160, 100 160"
fill="#e74c3c"/>
</svg>
绘制箭头
<svg width="200" height="100" xmlns="http://www.w3.org/2000/svg">
<path d="M 10 50 L 150 50 L 150 30 L 190 50 L 150 70 L 150 50"
fill="#3498db" stroke="#2980b9" stroke-width="2"/>
</svg>
绘制齿轮
<svg width="200" height="200" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
<path d="M 100 20 L 110 40 L 130 35 L 125 55 L 145 65 L 130 80
L 145 100 L 125 110 L 130 130 L 110 125 L 100 145
L 90 125 L 70 130 L 75 110 L 55 100 L 70 80
L 55 65 L 75 55 L 70 35 L 90 40 Z"
fill="#7f8c8d" stroke="#2c3e50" stroke-width="2"/>
<circle cx="100" cy="82" r="20" fill="#ecf0f1"/>
</svg>
命令速查表
| 命令 | 参数 | 说明 |
|---|---|---|
| M/m | x y | 移动到指定位置 |
| L/l | x y | 画直线到指定位置 |
| H/h | x | 画水平线 |
| V/v | y | 画垂直线 |
| C/c | x1 y1, x2 y2, x y | 三次贝塞尔曲线 |
| S/s | x2 y2, x y | 平滑三次贝塞尔曲线 |
| Q/q | x1 y1, x y | 二次贝塞尔曲线 |
| T/t | x y | 平滑二次贝塞尔曲线 |
| A/a | rx ry rot large sweep x y | 椭圆弧 |
| Z/z | 无 | 闭合路径 |
小结
路径是 SVG 中最灵活的绘图工具。直线命令适合绘制多边形和折线,曲线命令适合绘制平滑曲线。贝塞尔曲线通过控制点定义曲线形状,弧线命令可以绘制椭圆的一部分。掌握路径命令是创建复杂 SVG 图形的关键。