SVG 急速入门教程(05.自定义形状)

543 阅读8分钟

上一篇:基础形状(Basic Shapes)

本节我们讲解 3 种自定义图形:

  1. <path> 可以绘制任意的形状和曲线;
  2. <polyline> 绘制折线;
  3. <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)。

  1. M 3,10 把画笔移动到坐标 (3,10),此坐标变为当前坐标;
  2. L 10,0 从当前坐标画直线至坐标 (10,0),并将此坐标设为当前坐标;
  3. L 17,10 原理同上,画直线至坐标 (17,10)
  4. L 10,20 原理同上,画直线至坐标 (10,20)
  5. 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)),并将新坐标设为当前坐标。

  1. m 3,10 把画笔坐标偏移 (3,10),即往右移动3、往下移动10,偏移后的坐标变为当前坐标;
  2. l 7,-10 从当前坐标画直线到新的坐标(当前坐标偏移 (7,-10),即往右移动7、往上移动10),并将新坐标设为当前坐标;
  3. l 7,10 原理同上,偏移 (7,10)
  4. l -7,10 原理同上,偏移 (-7,10)
  5. 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 dx v dy 使用相对坐标。

  1. M 10,5 当前坐标变为 (10,5)
  2. H 30 从当前坐标画水平线至坐标 (30,5),X坐标不变;
  3. V 30 从当前坐标画垂直线至坐标 (30, 30),X坐标不变;
  4. H 0 从当前坐标画水平线至坐标 (0, 30),Y坐标不限;
  5. Z 关闭路径(并从当前坐标画直线至起始坐标)。

  1. M 10,5 当前坐标变为 (10,5)
  2. h 20 从当前坐标画水平线至新坐标,新坐标往右偏移 20(X坐标值加上20),Y坐标不变;
  3. v 25 从当前坐标画水平线至新坐标,新坐标往下偏移 25(Y坐标值加上20),X坐标不变;
  4. h -30 从当前坐标画水平线至新坐标,新坐标往左偏移 30(X坐标值减去20),Y坐标不变;
  5. 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) 分别是控制点坐标结束点坐标的坐标偏移。

  1. M 0,0 把画笔移动至坐标 (0,0)
  2. Q 10,0 10,10 绘制二次贝塞尔曲线,(0,0) 是起始坐标,(10,0) 是控制点坐标,(10,10) 是结束点坐标(并把此坐标设置为当前坐标);
  3. 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 ..." />
  • 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 表示终点坐标偏移量。

A/a 是英文单词弧线(Arc) 的首字母。

1.11. 简洁语法

为了缩减 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

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 中绘制文本。

下一篇:文本