SVG `path` 语法:图解指南

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您旅程的每个阶段提供云产品。 立即开始使用 200 美元免费积分!

<path> 元素在 SVG 中是终极绘图元素。 它可以绘制任何东西! 我听说,在幕后,所有其他绘图元素最终都使用路径。 path 元素采用单个属性来描述它所绘制的内容:d 属性。 它具有的值本身就是一个小型语法。 它看起来可能相当难以理解。 它是一大堆数字和字母,压缩成一个长字符串。 就像任何计算机一样,这里是有规律可循的。 我不是专家,但我认为深入研究会很有趣。

这是一个中等复杂路径的示例,我认为

<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" />

字母是 **命令**。 数字是 **传递给这些命令的值**。 所有逗号都是可选的(它们可以是空格)。

例如,第一个命令是 MM 从比喻意义上说,表示 *拿起笔并将其移动到 213.1, 6.7 的确切位置*。 现在还不要画任何东西,只是移动笔的位置。 因此,如果其他命令进行绘制,它现在将从该位置开始。

M 只是许多路径命令中的一种。 我数了一下,总共有 18 个。

许多(但不是全部)命令成对出现。 有一个 **大写** 版本和一个小写版本。 大写版本是 **绝对** 版本,小写版本是 **相对** 版本。 让我们继续以 M 为例

  • M 100,100 表示“拿起笔并将其移动到 100,100 的确切坐标”。
  • m 100,100 表示“从当前位置将笔移动 100 向下,100 向右”。

许多命令都有相同的设置。 小写版本会考虑“笔”当前的位置。

让我们看一下两个绝对命令

commands - CSS技巧<svg viewBox="0 0 100 100"> <path d=" M 50,50 L 100,100 " /> </svg> Pick up the pen and move it to 50,50Put down the penand draw a line to 100,100

然后是一个相对命令

commands - CSS技巧<svg viewBox="0 0 100 100"> <path d=" M 50,50 L 100,100 l 25,0 " /> </svg> From the currentposition, move right 25

就像 Mm 命令一样,Ll 接受两个数字:绝对或相对坐标。 还有另外四个命令本质上是线条命令的简化版本。 它们也绘制线条,但只接受一个值:水平或垂直。 当我们使用 l 25,0 时,我们可以使用 h 25,它表示“从笔当前位置开始,向右绘制 25”。 我想,更简洁。 它的兄弟 H,正如我们所料,表示绘制到确切的水平坐标 25。 Vv 分别向上和向下移动绝对位置和相对位置,正如您所料。

查看 Chris Nager 的这个演示,他用极少量的代码绘制了一个十字架,这得益于相对坐标绘制

看到 Chris 最后使用的字符了吗? ZZ(或 z,这没关系)“关闭”路径。 与任何其他命令一样,它是可选的。 这是一个简单易行的方法,可以绘制一条直接回到“笔”最后放下位置(可能是最后一个 Mm 命令)的直线。 它可以节省您重复第一个位置并使用线条命令回到那里的麻烦。

commands - CSS技巧<svg viewBox=”0 0 100 100″> <path d=” M 50,50 L 100,100 l 25,0 Z ” /> </svg> Draw a linestraight back to the start

让我们看看我们迄今为止涵盖的命令。

**M** x,y移动到 x,y 的绝对坐标
**m** x,y向右移动 x,向下移动 y(或向左和向上,如果值为负数)
**L** x,y绘制一条到 x,y 的绝对坐标的直线
**l** x,y绘制一条到相对位置(向右移动 x,向下移动 y(或向左和向上,如果值为负数))的直线
**H** x绘制一条水平线到确切的坐标 x
**h** x绘制一条相对于笔的水平线,向右移动 x(或向左移动,如果值为负数)
**V** y绘制一条垂直线到确切的坐标 y
**v** y绘制一条相对向下移动 y(或向上移动,如果值为负数)的垂直线
**Z**(或 **z**)绘制一条直线回到路径的起点

到目前为止,我们只看到了直线。 Path 对于直线来说是一个完全可以接受的元素和语法,尽管可以说,像 <line> 这样的元素对于直线形状可能具有更简单的语法,即使略微受限。

Path 的超能力是曲线! 有很多不同的类型。

记得我们看过的第一个示例代码使用了大量的 Cc 命令。 它们是“贝塞尔曲线”,需要更多数据才能完成它们的工作。

C 命令接受三个点。 前两个点定义了两个贝塞尔曲线控制柄的位置。 也许这个概念在 Adobe Illustrator 的钢笔工具等工具中很熟悉

最后三个点中的一个是曲线的终点。 曲线应该结束的位置。 这是一个插图

commands - CSS技巧<svg viewBox=”0 0 100 100″> <path d=” M 25,50 C 25,100 150,100 150,50 ” /> </svg> Bezier point #1Bezier point #2Final point

小写 c 命令完全相同,只是所有三个点都使用相对值。

S(或 s)命令与 C 命令是伙伴关系,因为它只需要 *两个* 点,因为它假定第一个贝塞尔点是最后一个 S 或 C 命令中使用的最后一个贝塞尔点的反射。

commands - CSS技巧<svg viewBox=”0 0 100 100″> <path d=” M 25,100 C 25,150 75,150 75,100 S 100,25 150,75 ” /> </svg> ASSUMED!Bezier PointFinal Point

Q 命令是最简单的命令之一,因为它只需要两个点。 它想要的贝塞尔点是一个“二次”曲线控制点。 就像起点和终点都共享一个控制柄结束位置一样。

我们不妨同时介绍 T。 它与 Q 是伙伴关系,就像 SC 是一样。 当 T 出现在 Q 之后时,假定控制点是前一个控制点的反射,因此您只需要提供最终点。

commands - CSS技巧<svg viewBox=”0 0 100 100″> <path d=” M 25,75 Q 50,150 75,100 T 150,150 ” /> </svg> Bezier PointFinal PointASSUMED!Final Point

A 命令可能是最复杂的命令。 或者至少需要最多的数据。 您需要提供定义椭圆宽度、高度和椭圆旋转方式的信息,以及终点。 然后是有关您希望路径沿着该椭圆走哪条路径的更多信息。 来自 MDN

路径有两种可能的椭圆,并且每个椭圆上有两种不同的可能路径,总共四种可能的路径。 第一个参数是大弧标志。 它只是确定弧度应该大于或小于 180 度; 最终,此标志决定了弧将在给定圆的哪个方向上移动。 第二个参数是扫掠标志。 它决定了弧线应该从负角度还是正角度开始移动,这实际上选择了你将绕行的两个圆中的哪一个。

Joni Trythall 的图形解释了来自 她关于 SVG 路径的文章 的 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绘制一条基于椭圆曲线的弧线。 首先定义椭圆的宽度和高度。 然后是椭圆的旋转。 连同终点,这将产生两个可能的椭圆。 因此弧线和扫掠要么是 0 要么是 1,并决定了哪个椭圆以及它将走哪条路径。
aeX,eY 的相对值相同

想看一些例子吗? 好吧

如果您正在最近发布的基于 Blink 的浏览器中查看,并且您有鼠标,您会看到一些悬停动画! 事实证明,您现在可以在 CSS 中设置路径数据。 例如……

<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 Path Visualizer 非常酷!


想了解更多关于 SVG 的信息吗? 我保证它真的非常酷。 我写了一整本书关于它。 它叫做 Practical SVG 而且它并不贵。