几个星期前在谈到基本的SVG图形时,我提到路径可以作为一个更常用的方法来创建任何形状。路径比基本图形更强大和灵活,可以用来创建任何一个基本图形。
使用路径你可以创建直线和曲线,也可以把它们连接起来,组成其它的形状。你可以结合两者来创建复杂的路径和子路径。路径可以被填充、描边或者用于剪裁其他元素。它们可以同时做这三种效果甚至更多。
如果你从图形编辑器导出SVG图像,它可能会把所有的形状和线条作为路径导出。如果你使用SVG,你会遇到更多的路径,所以了解一点它们的东西是很有意义的。
今天,我会讲一下路径元素以及你可以使用的不同的直线指令。下周,我将继续谈谈曲线指令。
路径元素
使用命名合适的路径元素创建一条路径,在路径元素内,通过一系列的指令和坐标定义了如下的一条路径。
<svg>
<path d="path data" />
</svg>
定义的路径(d
)使用了不同的指令,移动到一个新的点,然后绘制不同的直线和曲线。这篇文章的大部分内容以及接下来的文章,都将介绍这些指令。
路径元素可以带有一个pathLength
属性。这个属性接收一个非负数作为值,并使用这个值来覆盖浏览器计算的路径长度。
<svg>
<path d="path data" pathLength="non-negative-number" />
</svg>
我现在还不想过多地谈论pathLength
属性。它不会完全覆盖计算的路径,而是将其扩展到一定程度。这可能会影响到用于放置文本的路径的计算或者动画路径的计算,它也可能影响到不同的描边操作。
我们来看看不同路径的数据指令。我们将从简单的直线指令开始,然后下周讲曲线指令。
直线指令
这里有五种不同的直线指令,你可以使用它们来创建路径。
moveto
(M
或m
):移动到新的位置lineto
(L
或l
):从当前坐标画一条直线到一个新坐标horizontal lineto
(H
或h
):画一条水平线到新坐标vertical lineto
(V
或v
):画一条垂直线到新坐标closepath
(Z
或z
):关闭当前路径
你不需要将指令拼写出来,使用指令字母即可。指令字母大写表示坐标位置是绝对位置,指令字母小写表示坐标位置时相对位置。
moveto和lineto指令
这里有一个同时使用了moveto
和lineto
的简单示例。注意:这篇文章的代码都是使用内联SVG。
<svg width="600" height="400">
<path d="M 50 50 l 0 300 l 200 0 l 0 -300 l -200 0" fill="none" stroke="#000" stroke-width="2px" />
</svg>
首先,如果你已经阅读了本系列的之前的文章,让我们先简要地讲一下你应该先知道的内容。我创建一个SVG元素,并设置了一个高度和宽度的值。另外我设置了填充为none
,并为路径加了一个描边。这样我们就可以看到实际的直线路径,而不是一个填充图形。
路径的数据以移动到一个坐标为 x=50 y=50
(M 50 50
)的点为开始,每条路径都需要以一个moveto指令为开始。
接下来是一个lineto
指令,这里设置一个小写字母 l
(l 0 300
)。这个指令指的是从当前坐标(50 50
)画一条直线到相对坐标 (0 300
)。也就是说,直线会在水平方向绘制0px
,在垂直方向绘制300px
。
接着,是另一个lineto
指令 (l 200 0
),绘制一条200px
的水平线。后面的两条指令是 (l 0 -300
)和 (l -200 0
),这两条指令绘制了另外两条线,一条水平线和一条垂直线,和初始的水平线和垂直线在相反的方向上。
下面是绘制出来的完整的路径:
该路径首先移动到一个起点上,然后垂直向下绘制一条直线,再一条往右,一条往上,最后一条往左,回到起点结束路径。
你会注意到我没有指定单位,因为默认的单位是px
(像素),在谈到SVG的坐标系时我再仔细说说px
。还需要注意的一点是是,路径数据是不使用逗号隔开的指令列表,这些指令是一个跟着一个。
closepath指令
在前面的示例中,我们只使用了moveto
和lineto
指令来创建矩形的轮廓。现在我们把其它的三条指令也加入进来。
<svg width="600" height="400">
<path d="M 50 50 l 0 300 l 200 0 l 0 -300 Z" fill="none" stroke="#000" stroke-width="2px" />
</svg>
这里的代码和第一个示例绘制出的图形是一样的,不同的一点是:我用一个closepath
指令(Z
)替换了最后一个lineto
指令(l
)。因为没有指定坐标,所以使用 Z
和 z
效果是一样的。
正如你所看到的,它和前面的示例效果完全一样,但是closepath
使得我们可以不需要指定最后一组坐标。
horizontal lineto 和 vertical lineto指令
用closepath
替换最后一个lineto
让代码比最初的示例要简洁许多,但是我们还可以让它更简洁。
<svg width="600" height="400">
<path d="M 50 50 v 300 h 200 v -300 Z" fill="none" stroke="#000" stroke-width="2px" />
</svg>
这里我使用了vertical lineto
(v
) 和hosizontal lineto
(h
) 指令替换了中间的三个lineto
指令。这两个指令只需要x
和y
两个坐标值中的一个,另一个值它自己会确定为0
。
虽然它还是有很多坐标点,但已经比原来简洁了。当然你不会总是在绘制水平线或者垂直线这两种线条,但是当你需要绘制这两种线条时,比起普通的lineto
指令,你可能最好还是选择vertical lineto
(v
) 和hosizontal lineto
(h
) 这两个指令。
样式、空格和逗号
对于使用空格,你应该有一些调节措施。你可以通过移动或者添加空格,使得各个指令以及整个路径的数据阅读起来更简明。
<svg width="600" height="400">
<path d="M50 50 v300 h200 v-300 Z" fill="none" stroke="#000" stroke-width="2px" />
</svg>
在这里,我去掉了一些指令和它们的第一个值之间的空格。我还在最后一个坐标之后、下一条指令之前添加了额外的空格。
虽然逗号不是必要的,你也可以在每条指令后边使用他们来分隔x
和y
坐标。你不能在指令之间使用逗号,但是你可以在坐标之间使用。
<svg width="600" height="400">
<path d="M50,50 v300 h200 v-300 Z" fill="none" stroke="#000" stroke-width="2px" />
</svg>
我在路径起点的x
和y
值之间添加了一个逗号。我可以保留它们之间的空格,但是考虑到坐标之间没有空格的话更容易阅读。在这方面你可以灵活一些。
如果它和前面的指令是一样的,你也可以跳过这条指令。下面是第一个示例中使用了lineto
指令的路径,lineto
指令一条接一条,所以我把实际的指令删除了。希望这些间隔和逗号可以使得不同组的坐标更容易查看。
<svg width="600" height="400">
<path d="M50,50 l 0,300 200,0 0,-300 Z" fill="none" stroke="#000" stroke-width="2px" />
</svg>
这是有效的,但是我发现它阅读起来更混乱了。我比较喜欢坐标一个一个分开来的指令,但是对于你来说,怎样阅读起来才最简明,是你自己决定的。
<svg width="600" height="400">
<path d="M50 50
v300
h200
v-300
Z"
fill="none" stroke="#000" stroke-width="2px" />
</svg>
这可能是最容易阅读的,但是很明显坐标占据了大部分的空间。而且有一点大家要记住,在WordPress中内联SVG的唯一解决方案是,所有的代码都要写在一行上。
总结思考
经过我们前面所看的示例,相信你已经看出使用路径比使用简单的图形要更加灵活。这是最后一个示例:
<svg width="600" height="400">
<path d="M100,100
v200
M400 50
h-200"
fill="none" stroke="#000" stroke-width="2px" />
</svg>
我只定义了一条路径,却创建出了两条看似独立的直线。
只用一条指令创建两条明显断开的直线是很简单的,而且我们甚至还没有谈论到曲线,甚至文本遵循路径移动、动画按照路径创建等。
下周我会接着谈谈不同的曲线指令,在这一年内我也会讲到文本以及动画。
本文根据@Steven Bradley的《SVG Basics—Creating Paths With Line Commands》所译,整个译文带有我们自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处:http://www.vanseodesign.com/web-design/svg-paths-line-commands/。
如需转载,烦请注明出处:http://www.w3cplus.com/svg/svg-paths-line-commands.html