# 路径

path元素是 SVG基本形状中最强大的一个。 你可以用它创建线条,曲线,弧形等等。

path 元素的形状是通过属性d定义的,属性d的值是一个 “命令 + 参数” 的序列

每一个命令都有两种表示方式

  • 一种是用大写字母,表示采用绝对定位
  • 另一种是用小写字母,表示采用相对定位

# 直线命令

# M

<path> 元素里有 5 个画直线的命令,顾名思义,直线命令就是在两个点之间画直线。首先是“Move to”命令,M。

M 需要两个参数,分别是需要移动到的点的 x 轴和 y 轴的坐标。

M x y (or m dx dy)

这有一个比较好的例子,不过我们没画任何东西,只是将画笔移动到路径的起点,所以我们不会看到任何图案。但是,我把我们移动到的点标注出来了,所以在下面的例子里会看到 (10,10) 坐标上有一个点。

<svg width="310" height="100" style="border:1px solid">
  <path d="M 10 10"/>
  <circle cx="10" cy="10" r="2" fill="red"/>
</svg>

# L、H、V

能够真正画出线的命令有三个(M 命令是移动画笔位置,但是不画线),最常用的是“Line to”命令,L。

L 需要两个参数,分别是一个点的 x 轴和 y 轴坐标,L 命令将会在当前位置和新位置之间画一条线段。

 L x y (or l dx dy)

另外还有两个简写命令,用来绘制水平线和垂直线。H,绘制水平线。V,绘制垂直线。

H x (or h dx)
V y (or v dy) 
<svg width="310" height="100" style="border:1px solid">
  <path d="M 10 10 H 90 V 90 H 10 L 10 10"/>
  <circle cx="10" cy="10" r="2" fill="red"/>
  <circle cx="90" cy="90" r="2" fill="red"/>
  <circle cx="90" cy="10" r="2" fill="red"/>
  <circle cx="10" cy="90" r="2" fill="red"/>
</svg>

# Z

最后,我们可以通过一个“闭合路径命令”Z 来简化上面的 path,Z命令会从当前点画一条直线到路径的起点,尽管我们不总是需要闭合路径,但是它还是经常被放到路径的最后。另外,Z 命令不用区分大小写。

Z (or z)
<svg width="310" height="100" style="border:1px solid">
  <path d="M 10 10 H 90 V 90 H 10 L 10 10 z" fill="transparent" stroke="black"/>
</svg>

# 曲线命令

绘制平滑曲线的命令有三个,其中两个用来绘制贝塞尔曲线,另外一个用来绘制弧形或者说是圆的一部分。

# 三次贝塞尔曲线

我们从稍微复杂一点的三次贝塞尔曲线 C 入手,三次贝塞尔曲线需要定义一个点和两个控制点,所以用 C 命令创建三次贝塞尔曲线,需要设置三组坐标参数:

C x1 y1, x2 y2, x y (or c dx1 dy1, dx2 dy2, dx dy)
M x0 y0, C x1 y1, x2 y2, x y

这里(x0,y0)是曲线的起点,最后一个坐标 (x,y) 表示的是曲线的终点,另外两个坐标是控制点,(x1,y1) 是起点的控制点,(x2,y2) 是终点的控制点。

<svg width="190px" height="160px">
  <path d="M 10 10 C 20 20, 40 20, 50 10" stroke="black" fill="transparent"/>
  <path d="M 70 10 C 70 20, 120 20, 120 10" stroke="black" fill="transparent"/>
  <path d="M 130 10 C 120 20, 180 20, 170 10" stroke="black" fill="transparent"/>
  <path d="M 10 60 C 20 80, 40 80, 50 60" stroke="black" fill="transparent"/>
  <path d="M 70 60 C 70 80, 110 80, 110 60" stroke="black" fill="transparent"/>
  <path d="M 130 60 C 120 80, 180 80, 170 60" stroke="black" fill="transparent"/>
  <path d="M 10 110 C 20 140, 40 140, 50 110" stroke="black" fill="transparent"/>
  <path d="M 70 110 C 70 140, 110 140, 110 110" stroke="black" fill="transparent"/>
  <path d="M 130 110 C 120 140, 180 140, 170 110" stroke="black" fill="transparent"/>
</svg>

你可以将若干个贝塞尔曲线连起来,从而创建出一条很长的平滑曲线。通常情况下,一个点某一侧的控制点是它另一侧的控制点的对称(以保持斜率不变)。这样,你可以使用一个简写的贝塞尔曲线命令 S,如下所示:

S x2 y2, x y (or s dx2 dy2, dx dy)
<svg width="190px" height="160px">
  <path d="M 10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80" stroke="black" fill="transparent"/>
  <circle cx="10" cy="80" r="2" fill="red"/>
  <circle cx="40" cy="10" r="2" fill="red"/>
  <circle cx="65" cy="10" r="2" fill="red"/>
  <circle cx="95" cy="80" r="2" fill="red"/>
  <circle cx="125" cy="150" r="4" fill="blue"/> <!-- 这个对称点被自动计算了 -->
  <circle cx="150" cy="150" r="2" fill="red"/>
  <circle cx="180" cy="80" r="2" fill="red"/>
</svg>

# 二次贝塞尔曲线

另一种可用的贝塞尔曲线是二次贝塞尔曲线 Q,它比三次贝塞尔曲线简单,只需要一个控制点,用来确定起点和终点的曲线斜率。因此它需要两组参数,控制点和终点坐标。

Q x1 y1, x y (or q dx1 dy1, dx dy)
<svg width="190px" height="160px">
  <path d="M 10 80 Q 95 10 180 80" stroke="black" fill="transparent"/>
  <circle cx="10" cy="80" r="2" fill="red"/>
  <circle cx="95" cy="10" r="2" fill="red"/>
  <circle cx="180" cy="80" r="2" fill="red"/>
</svg>

就像三次贝塞尔曲线有一个 S 命令,二次贝塞尔曲线有一个差不多的 T 命令,可以通过更简短的参数,延长二次贝塞尔曲线。

T x y (or t dx dy)
<svg width="190px" height="160px">
  <path d="M 10 80 Q 52.5 10, 95 80 T 180 80" stroke="black" fill="transparent"/>
  <circle cx="10" cy="80" r="2" fill="red"/>
  <circle cx="52.5" cy="10" r="2" fill="red"/>
  <circle cx="95" cy="80" r="2" fill="red"/>
  <circle cx="137.5" cy="150" r="4" fill="blue"/> <!-- 这个对称点被自动计算了 -->
  <circle cx="180" cy="80" r="2" fill="red"/>
</svg>

# 弧形

弧形命令 A 是另一个创建 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
<svg width="325px" height="325px">
  <path d="M 80 80
           A 45 45, 0, 0, 0, 125 125
           L 125 80 Z" fill="green"/>
  <path d="M230 80
           A 45 45, 0, 1, 0, 275 125
           L 275 80 Z" fill="red"/>
  <path d="M 80 230
           A 45 45, 0, 0, 1, 125 275
           L 125 230 Z" fill="purple"/>
  <path d="M 230 230
           A 45 45, 0, 1, 1, 275 275
           L 275 230 Z" fill="blue"/>
</svg>

TIP

劝退,告辞!!!