Chapter 7. Paths
第 4 章中描述的所有基本形状都是更通用的 <path>
的速记形式。建议你使用这些快捷方式。它们有助于使您的 SVG 具有可读性和结构性。
<path>
元素更加的常规;通过指定一系列的线条(lines),弧形(arcs)和曲线(curves), 绘制任何任意形状的轮廓。
轮廓(outline)可以用笔画(stroke)来填充和绘制。就像基本形状(basic shapes)一样。这些paths(以及基本形状的简写)可以用来定义裁剪区域
或透明蒙版的轮廓。你们会再第10章看到。
描述轮廓(outline)的所有数据都再元素的 d 属性中(d 表示 data)。path data 包含一个字母的命令,比如 M 表示 moveto 或者 L 表示 lineto,
然后是特定命令的坐标信息。
moveto, lineto, and closepath
每个 path 必须以一条 moveto 命令开始。
这条命令字母是一个大写的 M 跟着 一个 x 坐标和 y 坐标,以逗号或者空格分隔。样例7-1有三个路径(paths)。第一个绘制了一条直线,第二个花了一个直角,
第三个花了两个30度的角。注意到,你可以使用逗号或者空格分隔 x 坐标和 y 坐标,就像所有三个路径演示的那样,结果如图7-1所示。
Example 7-1. Using moveto and lineto
http://oreillymedia.github.io/svg-essentials-examples/ch07/moveto-lineto.html
<svg width="150px" height="150px" viewBox="0 0 150 150"
xmlns="http://www.w3.org/2000/svg">
<g style="stroke: black; fill: none;">
<!-- single line -->
<path d="M 10 10 L 100 10"/>
<!-- a right angle -->
<path d="M 10, 20 L 100, 20 L 100,50"/>
<!-- two 30-degree angles -->
<path d="M 40 60 L 10, 60 L 40 42.68
M 60, 60 L 90 60 L 60, 42.68"/>
</g>
</svg>
更仔细地检查最后一条路径,将逗号替换为空格:
值 | 动作 |
---|---|
M 40 60 | 将笔移动到 (40,60) |
L 10 60 | 画一条线到 (10, 60) |
L 40 42.68 | 画一条线到 (40, 42.68) |
M 60 60 | 开始一个新的子路径;将笔移动到 (60,60)。移动是不会绘制线条的 |
L 90 60 | 绘制一条线到 (90,60) |
L 60 42.68 | 绘制一条线到 (60,42.68) |
注意:您可能已经注意到,path 数据看起来不太像XML属性的典型值。因为整个路径数据包含在一个属性中,而不是每个点或线段的单个元素中,当 XML解析器
将 path 读入文档对象模型结构时,path 占用的内存更少。此外,path 的紧凑符号允许在不需要大量带宽的情况下传输复杂的图形。
如果你想用 <path>
绘制一个矩形,你可以画出所有四条线,或者您可以绘制前三行,然后使用 closepath 命令,用大写 Z 字母表示,画一条直线回到
当前子路径的起始点。样例7-2 是图像7-2 的 SVG 文档,它显示了绘制一个矩形更困难的方法,用闭合路径绘制的矩形,以及通过打开和关闭两个subpaths
来画两个三角形的 path。
Example 7-2.Using closepath
<g style="stroke: black; fill: none;">
<!-- rectangle; all four lines -->
<path d="M 10, 10 L 40, 10 L 40, 30 L 10, 30 L 10, 10"/>
<!-- rectangle with closepath -->
<path d="M 60 10 L 90 10 L 90 30 L 60 30 Z"/>
<!-- two 30-degree triangles -->
<path d="M 40 60 L 10 60 L 40 42.68 Z
M 60 60 L 90 60 L 60 42.68 Z"/>
</g>
更仔细地检查最后一条path:
值 | 动作 |
---|---|
M 40 60 | 将笔移动到 (40, 60) |
L 10 60 | 绘制一条直线到 (10, 60) |
L 40 42.68 | 绘制一条直线到 (40, 42.68) |
Z | 画一条直线到子路径开始的地方(40, 60) 来关闭路径 |
M 60 60 | 开始一个新的子路径;将笔移动到(60,60)。不会绘制线条。 |
L 90 60 | 绘制一条线条到(90,60) |
L 60 42.68 | 绘制一条线条到(60, 42.68) |
Z | 画一条直线到子路径开始的地方(60, 60) 来关闭路径 |
用四条线绘制矩形和使用 closepath 命令之间还有另一个区别。当您关闭 path 时,起始线和结束线连结在一起,形成一个连续的 shape, 用于描边样式。
如果您使用宽笔画(wide strokes)或笔画线重叠(stroke-linecap)和笔画线链接效果(stroke-linejoin effects),那么差异时显而易见的。
Example 7-3.Individual lines versus closepath
<g style="stroke: gray; stroke-width: 8; fill: none;">
<!-- rectangle; all four lines -->
<path d="M 10 10 L 40 10 L 40 30 L 10 30 L 10 10"/>
<!-- rectangle with closepath -->
<path d="M 60 10 L 90 10 L 90 30 L 60 30 Z"/>
</g>
Relative moveto and lineto
以上命令均由大写字母表示,坐标假定为绝对坐标。如果您使用小写的命令字母,坐标将被解释为相对于当前笔的位置。因此,以下两个路径是等价的:
<path d="M 10 10 L 20 10 L 20 30 M 40 40 L 55 35"
style="stroke: black;"/>
<path d="M 10 10 l 10 0 l 0 20 m 20 10 l 15 -5"
style="stroke: black;"/>
如果路径以小写的m(moveto)开头,那么它的坐标将被解释为绝对位置,因为没有之前的笔位置可以用来计算相对位置。本章中的所有其他命令也有相同的大写和小写区别。大写命令的坐标是绝对坐标,小写命令的是相对坐标。closepath 命令没有坐标,它的大写命令和小写命令效果都是一样的。
Path Shortcuts
如果内容为往,设计为后,那么贷款效率就是保持网站平稳运行的皇家大臣。因为任何重要的绘图都将具有数十个坐标对的路径,所以<path>
元素具有快捷键,运行您以尽可能少的字节表示路径。
The Horizontal lineto and Vertical lineto Commands
水平线和垂直线是常见的快捷方式命令。一个 path 可以指定带有大写字母 H 的水平线命令,后面跟着绝对 x坐标,或者指定带有小写字母的 h 的水平线命令,后面跟着相对 x坐标。
与之相似的,一条垂直线通过大写字母 V 命令,后面跟随一个绝对 y坐标,或者一个小写字母 v 命令,后面跟随一个相对 y坐标。下面的表比较绘制水平线和垂直线的优点和缺点。
缩写 | 等价于 | 效果 |
---|---|---|
H 20 | L 20 current_y | 绘制一条线到绝对位置 (20, current_y) |
h 20 | l 20 0 | 绘制一条线到绝对位置 (current_x+20, current_y) |
V 20 | V current_x 20 | 绘制一条线到绝对位置 (current_x, 20) |
v 20 | l 0 20 | 绘制一条线到位置 (current_x, current_y+20) |
因此,下面的路径绘制了一个宽为 15个单位,长为 25个单位的矩形,左上角在坐标点(12, 24)。
<path d ="M 12 24 h 15 v 25 h -15 z" />
Notational Shortcuts for a Path
通过应用以下两个规则,路径也可以缩短:
- 你可以在大写字母L 和小写字母l 后面放置多组坐标,就像你在
<polyline>
元素中那样。以下六条 path 均绘制图7-4中显示的相同的菱形。开始的三个
是绝对坐标,后面的三个是相对坐标。第三个和第六个path有一有趣的转折。如果你在 moveto 后面放置多个坐标。第一对之后的所有坐标,都默认使用的 lineto 命令。
<g style="fill:none; stroke: black">
<path d="M 30 30 L 55 5 L 80 30 L 55 55 Z"/>
<path d="M 30 30 L 55 5 80 30 55 55 Z"/>
<path d="M 30 30 55 5 80 30 55 55 Z"/>
<path d="m 30 30 l 25 -25 l 25 25 l -25 25 z"/>
<path d="m 30 30 l 25 -25 25 25 -25 25 z"/>
<path d="m 30 30 25 -25 25 25 -25 25 z"/>
</g>
- 任何不必要的空格可以省删除。命令字母后面不需要空格,因为所有的命令都是一个字母。在数字和命令之间不需要空格,因为命令字母不能是数字的一部分。
正数和负数之间不需要空格,因为负数的前导负号不能是正数的一部分。这使您可以进一步减少前面清单中的第三个和第六个path。
<path d="M30 30 55 5 80 30 55 55Z"/>
<path d="m30 30 25-25 25 25-25 25z"/>