SVG基础——使用Line指令创建路径

发布于 彦子

几个星期前在谈到基本的SVG图形时,我提到路径可以作为一个更常用的方法来创建任何形状。路径比基本图形更强大和灵活,可以用来创建任何一个基本图形。

使用路径你可以创建直线和曲线,也可以把它们连接起来,组成其它的形状。你可以结合两者来创建复杂的路径和子路径。路径可以被填充、描边或者用于剪裁其他元素。它们可以同时做这三种效果甚至更多。

如果你从图形编辑器导出SVG图像,它可能会把所有的形状和线条作为路径导出。如果你使用SVG,你会遇到更多的路径,所以了解一点它们的东西是很有意义的。

今天,我会讲一下路径元素以及你可以使用的不同的直线指令。下周,我将继续谈谈曲线指令。

路径元素

使用命名合适的路径元素创建一条路径,在路径元素内,通过一系列的指令和坐标定义了如下的一条路径。

<svg>
  <path d="path data" />
</svg>

定义的路径(d)使用了不同的指令,移动到一个新的点,然后绘制不同的直线和曲线。这篇文章的大部分内容以及接下来的文章,都将介绍这些指令。

路径元素可以带有一个pathLength属性。这个属性接收一个非负数作为值,并使用这个值来覆盖浏览器计算的路径长度。

<svg>
  <path d="path data" pathLength="non-negative-number" />
</svg>

我现在还不想过多地谈论pathLength属性。它不会完全覆盖计算的路径,而是将其扩展到一定程度。这可能会影响到用于放置文本的路径的计算或者动画路径的计算,它也可能影响到不同的描边操作。

我们来看看不同路径的数据指令。我们将从简单的直线指令开始,然后下周讲曲线指令。

直线指令

这里有五种不同的直线指令,你可以使用它们来创建路径。

  • moveto(Mm):移动到新的位置
  • lineto(Ll):从当前坐标画一条直线到一个新坐标
  • horizontal lineto(Hh):画一条水平线到新坐标
  • vertical lineto(Vv):画一条垂直线到新坐标
  • closepath(Zz):关闭当前路径

你不需要将指令拼写出来,使用指令字母即可。指令字母大写表示坐标位置是绝对位置,指令字母小写表示坐标位置时相对位置。

moveto和lineto指令

这里有一个同时使用了movetolineto的简单示例。注意:这篇文章的代码都是使用内联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指令

在前面的示例中,我们只使用了movetolineto指令来创建矩形的轮廓。现在我们把其它的三条指令也加入进来。

<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)。因为没有指定坐标,所以使用 Zz 效果是一样的。

正如你所看到的,它和前面的示例效果完全一样,但是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指令。这两个指令只需要xy两个坐标值中的一个,另一个值它自己会确定为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>

在这里,我去掉了一些指令和它们的第一个值之间的空格。我还在最后一个坐标之后、下一条指令之前添加了额外的空格。

虽然逗号不是必要的,你也可以在每条指令后边使用他们来分隔xy坐标。你不能在指令之间使用逗号,但是你可以在坐标之间使用。

<svg width="600" height="400">
  <path d="M50,50  v300  h200  v-300  Z" fill="none" stroke="#000" stroke-width="2px" />
</svg>

我在路径起点的xy值之间添加了一个逗号。我可以保留它们之间的空格,但是考虑到坐标之间没有空格的话更容易阅读。在这方面你可以灵活一些。

如果它和前面的指令是一样的,你也可以跳过这条指令。下面是第一个示例中使用了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/

彦子

在校学生,本科计算机专业。逗比一枚,热爱前端热爱生活,喜欢CSS喜欢JavaScript喜欢SVG,爱玩PS玩AI玩啊逗比的软件。努力向上,厚积薄发。

如需转载,烦请注明出处:https://www.fedev.cn/svg/svg-paths-line-commands.htmlShop Nike Apparel, Shoes and Accessories