Olmsted

图解SVG中的path语句

Olmsted · 2016-12-27翻译 · 463阅读 原文链接

Path 元素乃是SVG中的终极绘图元素。它可以绘制任何东西!我听说所有绘制元素的底层,最终都是使用path来绘制的。Path 元素使用一个单独的属性来描述它缩绘制的图形:d 属性。它的值是一个完全属于自己的代码。它看起来确实是难以辨认,那是一个有着海量的数字和字母混在一起的长字符串。但是如任何计算机(译注:原文为Like anything computers,似乎作者想表达的是,like anything in computers 就像任何计算机例的东西一样),这看似音乐符号的东西有它的原理。我并不是专家,但是我想去研究它会挺有意思。

这是一段中等复杂的 path 代码,请见如下(译注:文中后面的译注可能会出现解释的代码段,会用空格取代逗号,在SVG中逗号和空格的作用是一样的,欢迎读者尝试。译者图方便,后面若有注释就采用空格了):

<path d="M213.1,6.7c-32.4-14.4-73.7,0-88.1,30.6C110.6,4.9,67.5-9.5,36.9,6.7C2.8,22.9-13.4,62.4,13.5,110.9
  C33.3,145.1,67.5,170.3,125,217c59.3-46.7,93.5-71.9,111.5-106.1C263.4,64.2,247.2,22.9,213.1,6.7z"/>

我们可以通过调整它的格式来更好地理解它(这依然是有效的代码):

<path d="
  M 213.1,6.7
  c -32.4-14.4-73.7,0-88.1,30.6
  C 110.6,4.9,67.5-9.5,36.9,6.7
  C 2.8,22.9-13.4,62.4,13.5,110.9
  C 33.3,145.1,67.5,170.3,125,217
  c 59.3-46.7,93.5-71.9,111.5-106.1
  C 263.4,64.2,247.2,22.9,213.1,6.7
  z" />

这些字母是控制符(commands,路径命令),数字是对应控制符的路径值(passing values,传递的参数).所有的控制符都是可选的(可以有空格)

例如,第一个控制符是M。M就好比,有一只假想中的笔,将它准确地移动到位置 213.1, 6.7。此时还没有绘制任何东西,只是将画笔移动到指定位置。所以如果后面别的控制符操作绘线,将会从这个位置开始。

M 是据我所统计有18个之多的控制符中的一个。

许多控制符(并非所有)都是成对出现。有大写和小写两个模式。大写的是绝对模式,小写的是相对模式。我们还是先使用M举例:

  • M 100,100 意味着 "拿起画笔并移动到准确的坐标: 100,100"

  • m 100,100 意味着 "从画笔当前的位置向下和向右移动画笔。"

许多控制符都有着相同的设置。其中小写的模式意味着画笔在当前的位置(译注:控制符后面的路径值的定位是相对当前位置计算的)。

我们先来看一下两个绝对控制命令, 命令为:拿起画笔移动到坐标 50,50 的位置,落笔并向 100,100 绘制一条直线。(译注:代码段为 "M 50 50 L 100 100")

紧接着一条相对的命令, 命令为:从(画笔)当前的位置,(坐标)向右移动25(译注:代码段为 "m 25 0")

就像Mm控制符一样,Ll也有两个数字:包括绝对或者相对坐标。另外还有4个其他的控制符算得上是直线控制符的简化版本。它们也是绘制直线,但是只需要一个属性值:水平和垂直。当我们使用l 25,0的时候可以用h 25,这意味着从画笔当前的位置,向右侧距其25的目标绘制。我认为这样更简洁了。它的大写兄弟H,我们可以猜想,意味着向确切的坐标25,0绘制一条直线(译注:绝对控制符中的路径值是相对当前坐标系中0 ,0的,在这个例子中即为坐标25,0)。你应该 肯定能够想到Vv 分别为绝对和相对垂直绘制(译注:原文为move,v命令执行的应该是draw,即绘制)。

请看这个Chirs Nager 的Demo,他在其中使用极其少量的代码绘制了一个十字,得益于相对坐标绘制的方法(译注:如果没看到效果就自己建一个html文件把其中对应的代码复制进去。反正我就是这么干滴):

Demo: Hand drawn SVG rounded plus, 由 Chris Nager (@chrisnager) 在 CodePen网站上制作,。

有没有看到最后Chris使用的字符 ZZ (或者是z,大小写无所谓),将这个路径闭合了。如同其他控制符,这个是可选的。当绘制一条直线回到画笔起始设置的坐标(应当就是最近的一次Mm控制符)的时候,这是一个简洁并且简单的方法。它为你省去了设定重复的起点位置和回到起点的直线命令。

命令: 绘制一条回到起点的直线。(译注:不知道这句话干嘛的。。后面还有很多类似的小段落,忽略基本不影响理解)

让我们来回顾一下目前我们已经见识过的控制符

M x,y 移动到绝对坐标 x,y

m x,y 相对向右移动x向下y(当x y的值为负值时,分别对应向左和向上)

L x,y 画一条直线到绝对坐标x,y

l x,y 画一条到相对向右x和向下的点的直线(当x y的值为负值时,分别对应向左和向上)

H x 画一条到准确坐标x的直线(译注:从当前位置到当前坐标系中 x,0 的坐标)

h x 画一条水平相对向右x的直线(当x的值为负值时,对应向左)

V y 画一条到准确坐标y的直线(译注:从当前位置到当前坐标系中 0,y的坐标)

v y 画一条水平相对向下y的直线(当y的值为负值时,对应向上)

Z (或 z) 绘制一条回到路径起点的直线

目前我们只见识了直线。Path 是一个有着完美代码支持的完美元素,尽管可能会有人争论认为,假如稍加限制(译注:目测是指限制线段不的段数,不要绘制多条线),像``元素(译注:原文的"" 是个什么鬼? 应该是要说polyline元素吧?附上一段polyline代码,三段的折线,相信初中数学水平就能看懂:<polyline points="46,99 77,97 117,80 137,63"></polyline>)可能对此有着更加简单的代码支持。

但是,path的超级功能在于曲线。曲线有几种不同的形式。

还记得在开始的例子中,我们看到代码中使用了很多Cc控制符。这些是贝塞尔曲线Bezier Curves),需要更多的数据去完成它们的功能。

C(大写)控制符需要三个点。开始的两个点决定了两个贝塞尔曲线控制点的位置。或许这个概念和Adobe Illustrator 中的钢笔工具(pen tool)很相似:

三个点中的最后一个是曲线的终点(译注:起点是M/m 后面的坐标)。这就是曲线将完成的地方。解释如下:

commands Bezier point #1Bezier point #2Final point(译注:这段实在不知道怎么理解,再次蒙了,所以就原文放这里了。应该是要表达C有控制点1#和控制点2#两个控制点吧)

小写的控制符c是完全一样的,只是三个点都的值是表示相对位置。

S(或是s)控制符是C控制符的好基友,在这里它只需要两个点,因为它认为自己的第一个控制点就是前一个S或者C控制符中的最后一个贝塞尔控制点。

commands ASSUMED!Bezier PointFinal Point(译注:还是一样。估计是想表达贝塞尔控制点为再次之前最后一个控制点,可也没指定自己的哪一个控制点嘛。。)

Q控制符是最简单的控制符之一,因为它只需要两个点。它需要的贝塞尔控制点是一个“二次”曲线控制点。就好比控制起始点和中点的贝塞尔控制点是同一个。

也许我同时们可以再看下T。它是Q的好基友,就好比SC的好基友一样。当T跟在Q后面的时候,它的控制点就被认为是前一个控制点的镜像,这样你只需要提供终点就可以了。

commands Bezier PointFinal PointASSUMED!Final Point(译注:想必不说都知道了什么原因了。表达最后贝塞尔控制点为再次之前最后一个控制点,自身就一个控制点,干嘛要强调是最后一个?跟上面一段调换一下貌似能合理一点了)

A 控制符可能是最复杂的,至少可以说是需要的参数最多。需要提供数据决定一个椭圆的的宽和高,还有椭圆的旋转角度以及椭圆的终点。然后还需要提供数据去决定选取那一条路径。摘自 MDN:

有两个可能的椭圆,每个椭圆分别能提供两条不同的路径以供绘制。第一个参数是大弧标识( large-arc-flag)。它简单的决定了弧是否大于180°;最终,这个标识决定了圆弧将在给定的园上朝哪个方向绘制。第二个参数是扫描标识(sweep-flag)。它决定了圆弧的运动方向是正角度还是负角度,本质上决定了围绕两个圆中的哪一个进行绘制。

Joni Trythall's 在其 SVG paths的文章中,清晰地用图像解释了 A 命令的原理:

下面是这些曲线明龙的说明:

C cX1,cY1 cX2,cY2 eX,eY 根据两个控制点,向指定的坐标绘制一条贝塞尔曲线

c 同上,只是坐标是相对坐标

S cX2,cY2 eX,eY C控制符基本上是将前一个S或者C控制命令中的最后一个控制点作为自己的第一个控制点。

s 同上,只是坐标是相对坐标

Q cX,cY eX,eY 根据一个控制点,向指定的坐标绘制一条贝塞尔曲线

q 同上,只是坐标是相对坐标

T eX,eY Q控制符基本上是将前一个Q或者T控制命令中的最后一个控制点作为自己的第一个控制点。

t 同上,只是坐标是相对坐标

A rX,rY rotation, arc, sweep, eX,eY 根据椭圆绘制一条曲线。首先定义椭圆的宽和高。然后是旋转角度,根据椭圆的终点(译注:eX,eY),这就决定出了两个可能的椭圆。arc 和 sweep 设定为0或者1来决定选择哪个椭圆的哪个路径进行绘制。

t 同上,只是eX,eY坐标是相对坐标

想看一些例子么?如下:

Chris Coyier (@chriscoyier)在CodePen 的demo: Simple Path Examples.

如果你用你的鼠标寻找最近的发布的令人眼前一亮的浏览器效果,你就能看到hover动画!因为现在在CSS中可以设置path的数值了。例如:

<svg viewBox="0 0 10 10">
  <path d="M2,5 C2,8 8,8 8,5" />
</svg>
svg:hover path {
  transition: d 0.2s;
  d: path("M2,5 C2,2 8,2 8,5");
}

关于SVG想要了解跟多么?我保证这真的很酷。我写了一整本关于它的书,它就是 Practical SVG 并且不是很贵(译注:晕,到最后发现是个卖书的).

译者Olmsted尚未开通打赏功能

相关文章