本节我们讲解 3 种自定义图形:
<path>可以绘制任意的形状和曲线;<polyline>绘制折线;<polygon>绘制多边形。
1. 路径(<path>)
<path> 是 SVG 中最常使用的元素,因为它可以绘制任意你想要的形状。
1.1. 基本语法
<svg width="100%" height="100%" viewBox="0 0 400 400" xmlns="http://www.w3.org/2000/svg">
<path d="{{directions}}" pathLength="{{lengthOfPath}}" fill="orange" stroke="black" stroke-width="3" />
</svg>
d表示一系列的绘图指令(directions),例如移动坐标、绘制直线、绘制曲线等共 20 个;pathLength手动设置 path 的长度,此属性我们在后面章节讲解 stroke 时会说明的;stroke表示路径线条的颜色;stroke-width表示路径线条的宽度;fill表示路径封闭区域的背景填充色。
1.2. M 和 L 指令
M 表示 MoveTo 指令,是指把画笔移动到某个坐标;
L 表示 LineTo 指令,是指从画笔当前的坐标绘制直线到某个坐标。
<svg>
<path d="
M x,y
L a,b
......" />
</svg>
M x,y表示把画笔移动到坐标(x,y)L a,b表示从画笔的当前的坐标(也就是刚才的(x,y))画直线到(a,b)
画笔的当前坐标默认为 (0,0)。
M 3,10把画笔移动到坐标(3,10),此坐标变为当前坐标;L 10,0从当前坐标画直线至坐标(10,0),并将此坐标设为当前坐标;L 17,10原理同上,画直线至坐标(17,10);L 10,20原理同上,画直线至坐标(10,20);L 3,10原理同上,画直线至起始(3,10)。
1.3. m 和 l 指令
上面的 M L 指令使用的是绝对坐标,而 m l 指令使用的是相对坐标,除此以外其他都是相同的。
<svg>
<path d="
m x,y
l a,b
......" />
</svg>
m x,y表示把画笔坐标偏移(x,y);l a,b表示从当前坐标画直线到新的坐标(当前坐标偏移(a,b)),并将新坐标设为当前坐标。
m 3,10把画笔坐标偏移(3,10),即往右移动3、往下移动10,偏移后的坐标变为当前坐标;l 7,-10从当前坐标画直线到新的坐标(当前坐标偏移(7,-10),即往右移动7、往上移动10),并将新坐标设为当前坐标;l 7,10原理同上,偏移(7,10);l -7,10原理同上,偏移(-7,10);l -7,-10原理同上,偏移(-7,-10),回到了起始坐标。
1.4. Z 和 z 指令
上面的示例中,我们从起始坐标 (3,10) 处 open 了一条 path,然后绘制了几条直线,最后回到了起始坐标 (3,10),然而却没有完全 close 这条 path:
- 蓝色圆圈标注的地方没有闭合
解决这个问题的方法就是使用 Z 或 z 即 close-path 指令(大小写不敏感,Z 和 z 一模一样的效果):
- 使用
Z代替了L3,10
1.5. H/h 和 V/v 指令
L/l 指令可以绘制任意的直线,同时 SVG 还提供了 H/h V/v 专门用于绘制水平和垂直的直线。
<path d="... H x V y ..." />
<path d="... h dx v dy ..." />
H x从当前坐标水平画线至(x, 当前Y坐标),并将此坐标设为当前坐标;V y从当前坐标垂直画线至(当前X坐标, y),并将此坐标设为当前坐标;h dxv dy使用相对坐标。
M 10,5当前坐标变为(10,5);H 30从当前坐标画水平线至坐标(30,5),X坐标不变;V 30从当前坐标画垂直线至坐标(30, 30),X坐标不变;H 0从当前坐标画水平线至坐标(0, 30),Y坐标不限;Z关闭路径(并从当前坐标画直线至起始坐标)。
M 10,5当前坐标变为(10,5);h 20从当前坐标画水平线至新坐标,新坐标往右偏移 20(X坐标值加上20),Y坐标不变;v 25从当前坐标画水平线至新坐标,新坐标往下偏移 25(Y坐标值加上20),X坐标不变;h -30从当前坐标画水平线至新坐标,新坐标往左偏移 30(X坐标值减去20),Y坐标不变;Z关闭路径(并从当前坐标画直线至起始坐标)。
1.6. Q 和 q 指令
Q 和 q 指令用于绘制二次贝塞尔曲线(Quadratic Bézier Curves),关于贝塞尔曲线原理请参考:知乎专栏-贝塞尔曲线。
要绘制二次贝塞尔曲线,需要3个点坐标:起始点坐标、控制点坐标、结束点坐标。
<path d="... Q x,y a,b" />
<path d="... q dx,dy da,db" />
- 其中画笔的当前坐标为起始坐标,
(x,y)是控制点坐标,(a,b)是结束点坐标(绘制结束后,把此坐标设置为当前坐标)。- 小写
q表示使用相对坐标,(dx,dy)(da,db)分别是控制点坐标和结束点坐标的坐标偏移。
M 0,0把画笔移动至坐标(0,0);Q 10,0 10,10绘制二次贝塞尔曲线,(0,0)是起始坐标,(10,0)是控制点坐标,(10,10)是结束点坐标(并把此坐标设置为当前坐标);Z连接当前坐标(10,10)至路径的起始坐标(0,0)。
1.7. T 和 t 指令
T/t 指令总是跟随在一个 Q/q 指令之后,表示在前一个二次贝塞尔曲线后再绘制一条平滑二次贝塞尔曲线。
<path d="... T x,y" />
<path d="... t dx,dy" />
- 前一条曲线的结束点坐标为本次曲线的起始点坐标;
- 本次曲线的控制点坐标是根据切线自动计算的;
(x,y)是本次曲线的结束点坐标;- 小写
t使用相对坐标,(dx,dy)是结束点坐标相较于当前坐标的偏移量。
- 第一条曲线是由 2 个 Q 指令绘制的,第二个 Q 指令的控制点是手动输入的
- 第二条曲线是由 1 个 Q 指令和 1 个 T 指令绘制的,T 指令的控制点是根据切线自动计算计算出来的
T/c指令总是跟在Q/q指令之后。
1.8. C 和 c 指令
C/c 指令用于会议三次贝塞尔曲线(Cubic Bézier Curves)。
要绘制三次贝塞尔曲线,需要4个坐标:起始点坐标、两个控制点坐标、结束点坐标。
<path d="... C x1,x2 x2,y2 a,b ..." />
<path d="... c dx1,dx2 dx2,dy2 da,db ..." />
- 其中起始点坐标就是当前坐标;
(x1,y1)(x2,y2)是两个控制点坐标;(a,b)是结束点坐标;- 小写
c表示使用相对坐标,(dx1,dy1)(dx2,dy2)(da,db)是控制点和结束点的坐标偏移。
1.9. S 和 s 指令
与二次曲线一样,三次曲线也支持平滑曲线(第一个控制点坐标是自动计算的,只需要提供第2个控制点坐标)。
<path d="... S x2,y2 a,b ..." />
<path d="... s dx2,dy2 da,db ..." />
- 其中起始点坐标就是当前坐标;
- 第一个控制点坐标是自动计算的;
(x2,y2)是第2个控制点坐标;(a,b)是结束点坐标;- 小写
s表示使用相对坐标,(dx2,dy2)(da,db)是第2个控制点和结束点的坐标偏移。
S/s指令总是跟在C/c指令之后。
1.10. A 和 a 指令
贝塞尔曲线虽然灵活,但是却无法绘制完全的(椭)圆弧形(Elliptical Curves),所以 SVG 提供了 A 和 a 指令。
<path d="... A rx ry x-axis-rotation large-arc-flag sweep-flag x y ..." />
<path d="... a rx ry x-axis-rotation large-arc-flag sweep-flag dx dy ..." />
rxX轴半径;ryY轴半径,如果 rx=ry,则绘制的是标准圆弧;如果rx≠ry,则绘制的是椭圆弧;x-axis-rotationX轴旋转角度;large-arc-flag1: 绘制圆形的大弧一侧,0: 绘制小弧一侧;sweep-flag1: 顺时针方向,0: 逆时针方向;x y弧线的终点坐标,起点坐标是画笔的当前坐标;dx dy表示终点坐标偏移量。
A/a是英文单词弧线(Arc) 的首字母。
1.11. 简洁语法
为了缩减 SVG 文件大小,提高网络传输效率,以上的指令可以有以下的简写方式:
M x,y→Mx,yM x1,y1 L x2,y2→Mx1,y1 x2,y2L x1,y1 L x2,y2 L x3,y3→Lx1,y1 x2,y2 x3,y3L-1,-1→L-1-1M0.5,0.9→M.5,.9
2. 折线(<polyline>)
<polyline points="x1,y1 x2,y2 x3,y3 x4,y4 ......" />
points表示的是连续的坐标,(x1,y1)是第一个坐标,(x2,y2)是第二个坐标,以此类推;- 坐标总是绝对的;
- 坐标可以用空格或逗号隔开,
x1,y1 x2,y2 x3,y3=x1 y1 x2 y2 x3 y3
3. 多边形(<polygon>)
<polygon points="x1,y1 x2,y2 x3,y3 x4,y4 ......" />
<polygon>与<polyline>的语法几乎一样,除了<polygon>会自动把最后一个坐标与第一个坐标相连,形成闭合;
4. 相关 DOM 接口
5. 小结
本节介绍了 <path> <polyline> <polygon> 的用法,接下来我们介绍如何在 SVG 中绘制文本。