15.SVG path元素

SVG<path>元素用于绘制组合线条、弧线、曲线等填充或非填充的高级形状。<path>元素可能是所有SVG形状中最高级功能最多的形状。它可能也是最难掌握的元素。

SVG Path教程视频版

视频版教程如下:

Path示例

让我们从一个简单的SVG<path>示例开始:

<svg xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink">

    <path d="M50,50
             A30,30 0 0,1 35,20
             L100,100
             M110,110
             L100,0"
          style="stroke:#660000; fill:none;"/>    
</svg>

下面是最终结果图片:

注意看图像如何包含一个圆弧和两条线段,已经第二条线如何不与第一个圆弧和线连接。

<path>元素的所有绘图都在d属性中指定。d属性包含绘制命令。上面的例子中,M发出“移至”命令,A发出“弧”命令,L发出“线段”命令。这些命令都作用在一个“虚拟画笔”。这支笔可以移动,绘制形状等。

设置和移动画笔

<path>元素的d属性中的第一个绘图命令应始终是移动命令。在你绘制任何东西之前,你都应该将虚拟画笔移动到某个位置。可以通过M命令做到这一点。示例代码如下:

<svg xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink">

    <path d="M50,50"
          style="stroke:#660000; fill:none;"/>
</svg>

上述例子中,将虚拟画笔移动到了点50,50处。下一个绘制命令将从这个点开始。

线条

使用<path>元素绘制一条线可能是最简单的命令。绘制线条使用Ll(小写L)命令完成。示例如下:

<svg xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink">

    <path d="M50,50
             L100,100"
          style="stroke:#660000; fill:none;"/>
</svg>

这个例子绘制了一条从点50,50(M命令的点)到点100,100(L命令的点)的线段。结果如下图:

Ll命令之间的区别在于,大写版本(L)命令后跟的是一个绝对定位的点,而小写版本(l)命令后跟的是一个相对定位的点。相对点是虚拟画笔开始绘制线之前的点加上l命令后跟的坐标。

如果虚拟画笔定位在50,50点,并且你使用了l100,100命令,线段将绘制到点50+100,50+100 = 150,150。如果使用L100,100命令,线段将被精确地绘制到点100,100,而不会考虑虚拟画笔的位置。

移动虚拟画笔绘图

路径形状始终会从虚拟画笔的最后一个点绘制到一个新点。每一个绘制命令都带有一个终点。执行命令后,虚拟画笔将位于该绘图命令的结束点。下一个绘图命令将从该点开始。

弧线

<path>元素使用Aa命令可以绘制圆弧。与线段一样,大写命令(A)对其终点使用绝对坐标,而小写名(a)使用相对坐标(相对于起点)。示例如下:

<svg xmlns="http://www.w3.org/2000/svg"
    xmlns:xlink="http://www.w3.org/1999/xlink">

    <path d="M50,50
             A30,50 0 0,1 100,100"
          style="stroke:#660000; fill:none;"/>
</svg>

结果图片如下:

这个例子绘制了一条从点50,50到点100,100A命令最终指定)的圆弧。

圆弧的半径有A命令上的前两个参数指定。第一个参数是rx(x方向上的半径),第二个参数是ry(y方向上的半径)。将rxry设置为相同的值会生成一个圆形的圆弧。将rxry设置为不同的值会生成一个椭圆的圆弧。上面的例子中,rx被设置为30ry被设置为50

A命令上的第三个参数是x-axis-rotation。这将设置相对于正常x轴旋转一定角度的弧的x轴。上面的例子中x-axis-rotation被设置为0。大部分情况下,你不需要改变这个参数。

第四和第五个参数分别是large-arc-flagsweep-flaglarge-arc-flag参数决定了绘制满足起点、终点、rxry的大圆弧还是小圆弧。下面一个例子中,绘制了4个圆弧,每个圆弧带有large-arc-flagsweep-flag的不同组合:

<path d="M40,20  A30,30 0 0,0 60,70"
    style="stroke: #cccc00; stroke-width:2; fill:none;"/>

<path d="M40,20  A30,30 0 1,0 60,70"
    style="stroke: #ff0000; stroke-width:2; fill:none;"/>

<path d="M40,20  A30,30 0 1,1 60,70"
    style="stroke: #00ff00; stroke-width:2; fill:none;"/>

<path d="M40,20  A30,30 0 0,1 60,70"
    style="stroke: #0000ff; stroke-width:2; fill:none;"/>

结果如下:

四个不同的圆弧都是从点40,20绘制到点60,70。一个长圆弧、一个小圆弧、以及它们两个的镜像。large-arc-flag决定了绘制大圆弧还是小圆弧。sweep-flag决定了圆弧是否为从起点到终点的镜像。其实,sweep-flag控制了圆弧绘制的方向(顺时针或逆时针),这就导致了“镜像”效果。

绘制的第一个圆弧是黄色弧。large-arc-flag被设置为0表示将绘制较小的弧。sweep-flag也被设置为0表示圆弧非镜像版。下面是一个黄色圆弧:

第二个圆弧是红色弧。large-arc-flag被设置为1表示绘制从点40,20到点60,70之间的两个可能的圆弧中较大的那个。下面将黄色和红色圆弧绘制在一起说明他们的区别:

绿色和蓝色圆弧(从前面例子中的所有四个圆弧看出)与黄色和红色圆弧相同,只是它们的sweep-flag被设置为1。这就意味着,它们将从起点到终点的轴上绘制镜像版的弧。

二次贝塞尔曲线

也可以使用<path>元素绘制二次贝塞尔曲线。可以通过Qq命令完成绘制二次贝塞尔曲线。和线段一样,大写命令(Q)使用绝对坐标,小写命令(q)使用相对坐标(相对于起点)。下面是一个简单的二次曲线例子:

<path d="M50,50 Q50,100 100,100"
      style="stroke: #006666; fill:none;"/>

结果图片如下:

该示例从点50,50到点100,100绘制了一条二次贝塞尔曲线,控制点为50,200。控制点是Q命令上设置的前两个参数。

控制点就像磁铁一样拉动曲线。曲线上的点越接近控制点,控制点拉入越多,意味着更接近控制点。下面是在图像上绘制控制点的更多示例:

事实上,如果你从起点到控制点绘制一条线,再从控制点到终点绘制另一条线,那么这两条线的中点之间的连线将是曲线的切线。如图所示:

三次贝塞尔曲线

使用Cc命令绘制三次贝塞尔曲线。三次贝塞尔曲线类似于二次贝塞尔曲线,但是它有两个控制点。和线段一样,大写命令(C)使用其终点的绝对坐标,而小写命令(c)使用相对坐标(相对于起始点)。示例代码如下:

<path d="M50,50 C75,80 125,20 150,50"
      style="stroke: #006666; fill:none;"/>

下面是绘制了控制点的图像:

你可以使用三次贝塞尔曲线创建高级曲线。如下图几个例子:

闭合路径

<path>元素具有可用于闭合路径的快捷命令,意味着绘制一条从终点到起点的线段。闭合命令为Z(或者z,闭合路径的大小写命令没有区别)。示例如下:

<path d="M50,50 L100,50 L100,100 Z"
    style="stroke: #006666; fill:none;"/>

下面是结果图片:

组合命令

你可以在同一个<path>元素中组合路径命令,代码如下:

<path d="M100,100
         L150,100
         a50,25 0 0,0 150,100
         q50,-50 70,-170
         Z"
      style="stroke: #006666; fill: none;"/>

这个例子绘制了一条直线、一个圆弧、一条二次贝塞尔曲线,并绘制了一条返回起始点的直线来闭合路径。结果如下图:

填充路径

你可以使用CSS属性fill来填充路径,示例代码如下:

<path d="M100,100 L150,100 L150,150  Z"
      style="stroke: #0000cc;
             stroke-width: 2px;
             fill  : #ccccff;"/>

结果如图所示:

可以发现图形内部用浅蓝色填充。

标记

你可以在<path>元素上使用标记。标记是位于路径的开始、中间和结束处的小符号,用来显示路径的方向。例如,在路径开始处的圆形或正方形,以及在结束处的箭头。

marker元素章节将会对标记作详细介绍。

符号缩写

如果你需要多次使用相同的命令,可以省略命令字母,仅仅需要提供一组额外的参数。示例如下:

<path d="M10,10   l100,0  0,50  -100,0  0,-50"
      style="stroke: #000000; fill:none;" />

此例子演示了如何将其他参数传递给l命令,如同l位于每组参数前面一样。这也适用于其他路径命令。结果图片如下:

路径命令

下面是SVGpath元素中可能的命令的一个列表。每个命令由一个字母和一组数字(坐标等)组成,它们是该命令的参数。大写命令通常将坐标参数解释为绝对坐标。小写命令通常将坐标参数解释为当前虚拟画笔的相对位置。

命令

参数

名称

描述

M

x,y

移至

将虚拟画笔移动到指定点x,y处而不绘制图。

m

x,y

移至

将虚拟画笔移动至相对于其当前坐标的x,y处而不进行绘图操作。

L

x,y

线路

从虚拟画笔当前位置绘制一条到x,y点的直线。

l

x,y

线路

从虚拟画笔当前位置绘制一条到相对于画笔当前位置的x,y点的直线。

H

x

水平线

绘制一条到指定点(x坐标由参数指定,y坐标为虚拟画笔当前的纵坐标)的水平线。

h

x

水平线

绘制一条到指定点(x坐标为虚拟画笔当前横坐标+指定的x,y坐标为虚拟画笔当前的纵坐标)的水平线。

V

y

垂直线

绘制一条到指定点(x坐标为虚拟画笔当前横坐标,y坐标由参数指定)的垂直线。

v

y

垂直线

绘制一条到指定点(x坐标为虚拟画笔当前横坐标,y坐标为虚拟画笔当前的纵坐标+参数指定的值)的垂直线。

C

x1,y1 x2,y2 x,y

曲线

从画笔当前点到x,y点绘制一条三次贝塞尔曲线。x1,y1和x2,y2是曲线的开始和结束控制点,控制其如何弯曲。

c

x1,y1 x2,y2 x,y

曲线

与C相同,但是坐标点为相对于画笔坐标的位置。

S

x2,y2 x,y

平滑曲线缩写

从画笔位置到点x,y绘制一条三次贝塞尔曲线。x2,y2为结束控制点。开始控制点与前一条曲线的结束控制点相同。

s

x2,y2 x,y

平滑曲线缩写

与S相同,但是坐标点为相对于画笔坐标的位置。

Q

x1,y1 x,y

二次贝塞尔曲线

从画笔当前坐标到x,y点绘制一条二次贝塞尔曲线。x1,y1是控制曲线如何弯曲的控制点。

q

x1,y1 x,y

二次贝塞尔曲线

与Q相同,但是坐标点为相对于画笔坐标的位置。

T

x,y

平滑二次贝塞尔曲线缩写

从画笔位置到点x,y绘制一条三次贝塞尔曲线。控制点与所使用的的最后一个控制点相同。

t

x,y

平滑二次贝塞尔曲线缩写

与T相同,但是坐标点为相对于画笔坐标的位置。

A

rx,ry x-axis-rotation large-arc-flag,sweepflag x,y

椭圆弧

从当前点到x,y点绘制一条椭圆弧。rx和ry为椭圆在x和y方向上的半径。x-rotation确定圆弧围绕x轴旋转的角度。当rx和ry的值不同时,它才会有效果。large-arc-flag似乎没有被使用(可以为0或1)。值(0或1)都不会改变圆弧。

a

rx,ry x-axis-rotation large-arc-flag,sweepflag x,y

椭圆弧

与A相同,但是坐标点为相对于画笔坐标的位置。

Z

闭合路径

通过从当前点到第一个点绘制一条线来关闭路径。

z

闭合路径

通过从当前点到第一个点绘制一条线来关闭路径。

最后更新于