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