Overview

如果你曾经看过一个 icon 的 SVG 代码,你可能会注意到他们通常是有一个 <path> 元素和一个神秘的 d 属性实现的。 你可能以为他们不过是设计师最喜欢的矢量图形编辑器的输出,虽然可能是正确的,但有些过度简化了。

理解这个属性的内部运作机制将是前端技能的一大助力,它让你能够做到以前从未想过的事情,比如制作弯曲的动画。 这份指南将会谈到 d 属性,也被称为 path data

A Path is a Series of Commands 路径是一系列命令

d 属性实际上是一系列命令,告诉浏览器如何绘制 path,如果将属性内容规范一下,将会是下面这样:

PLAINTEXT
M 12.0 7.2
C 10.5 5.6 8.1 5.2 6.3 6.7
C 4.5 8.1 4.2 10.6 5.7 12.4
L 12.0 18.3
L 18.3 12.4
C 19.7 10.6 19.5 8.1 17.7 6.7
C 15.8 5.2 13.4 5.6 12.0 7.2
Z
Click to expand and view more

为了绘制出 path,浏览器按照顺序执行这些命令,每个命令绘制一小部分。 所有的 path 命令都遵循同样的语法,单个字母 + 一系列数字,字母代表命令类型,二数字则是命令的参数。

可以将命令理解为函数调用,字母是函数名称,数字是函数参数:

PLAINTEXT
M(12, 7.2);
Click to expand and view more

Absolute and Relative Commands 绝对与相对命令

命令代码既可以是大写,也可以是小写。

例如下面命令

PLAINTEXT
M 10.0 10.0 # move
L 5.0  5.0   # line
M 10.0 10.0 # move
l 5.0  5.0   # line
Click to expand and view more

这里有两条从 (10, 10) 开始的直线,参数都为 (5, 5)

Curors

SVG path 的核心是 cursor。 所有的 path 命令都使用 cursor 决定从哪里开始绘制,并且所有 path 命令都会移动光标,以确保下一条命令移动的起始位置。

考虑下面命令

PLAINTEXT
M 5.0 5.0   # move
v 5.0       # relative vertical line
L 10.0 15.0 # move
h 5.0       #relative vertical line
Click to expand and view more

一开始 cursor 在左上角的 (0, 0),然后后面三条命令将 cursor 移动:(5, 5) -> (5, 10) -> (10, 15) -> (15, 15)

一般来说光标会停在当前 path 结束的地方,毕竟大多数时候你希望路径连接起来。 当前路径的结束位置取决于是 absolute (绝对) 还是 relative (相对)。

Move Command

该命令只会移动 cursor 并不会绘制任何东西

PLAINTEXT
M <x> <y>
m <dx> <dy>
Click to expand and view more

当你想要绘制不相连的路径的时候,这个命令十分有用

PLAINTEXT
M 3.0 5.5         # move
q 2.0 2.0 0.0 4.0 # relative quadratic curve
m 3.0 -6.0        # relative move
q 4.0 4.0 0.0 8.0
m 3.0 -10.0
q 4.0 6.0 0.0 12.0
Click to expand and view more

Lines

上面介绍了 cursor 光标,现在来进行绘制。

首先是直线,l 命令绘制一条从当前 cursor 开始,到 (x, y) 结束的直线。

PLAINTEXT
M 5.0 5.0
l 15.0 10.0
Click to expand and view more

和 m 命令移动 cursor 一样移动,但是会绘制一条直线。

Vertical and Horizontal Lines

还可以使用 HV 命令绘制具体方向的线条,H 绘制水平线,V 绘制竖线。

PLAINTEXT
M 13.0 5.0
h -6.0
V 15.0
H 13.0
M 7.0 10.0
h 4.0
Click to expand and view more

上面命令绘制了一个字母 E 形状的图形,中间略短。

The Close Path Command

最后一个类型的线条命令是 close path command z,这条命令从当前的 cursor 命令开始,到 path 起始的位置结束,绘制一条直线。即无需显式去闭合图形,直接使用 Z 命令就行了。

PLAINTEXT
M 10.0 5.0
l -5.0 10.0
h 10.0
Z
Click to expand and view more

上面命令绘制了一个三角形。

有趣的是,Z 命令的确有一个小写的相对命令,但是由于该命令没有任何参数,因此两个命令的效果都相同。

Z 做的闭合不仅是加了一条线而已,例如下面这个爱心的例子

SVG
M 11.995 7.23319
C 10.5455 5.60999 8.12832 5.17335 6.31215 6.65972
C 4.4959 8.14609 4.2403 10.6312 5.66654 12.3892
L 11.995 18.25
L 18.3235 12.3892
C 19.7498 10.6312 19.5253 8.13046 17.6779 6.65972
C 15.8305 5.18899 13.4446 5.60999 11.995 7.23319
Click to expand and view more

这个心的 icon 中,起始和结束都是 (11.995, 7.23319) 但实际上如果仔细观察连接处,就会发现这里的两条曲线交汇处会有部分不自然的连接,如果最后再加上 Z 就能让两跳曲线更加自然地闭合。

Curves

实际上,如果只使用直线的话,只用 <line /> 元素是就行了,SVG path 真正的强大之处是能够绘制曲线,因此下面来探讨曲线。 在 SVG path 中有 3 种绘制的曲线:quadratic bezier curves, cube berizer curvesarcs.

Beizer Curves

Beizer curve 是由一系列叫做 control points 的控制点定义的。 SVG path 支持两类 beizer curves:

控制点越多,曲线也就越复杂

Quadratic Curves

虽然 cube beizer curves 更加灵活,但当不需要更加复杂形状的时候,quadratic beizer curves 更加容易使用

使用命令 Q 绘制曲线该

PLAINTEXT
Q controlX controlY endX endY
Click to expand and view more

例如这条曲线,创建了一个圆角

PLAINTEXT
M 5.0 5.0
v 5.0
Q 5.0 15.0 15.0 15.0
h 5.0
Click to expand and view more

Chaining Quadratic Curves

如果想要写多个连续的二次曲线,可以这样实现

PLAINTEXT
Q 5 10 10 10
Q 15 10 15 15
Click to expand and view more

但实际上有更好的实现该功能的方法 - 即使用 T 命令

PLAINTEXT
M 5.0 5.0
Q 5.0 10.0 10.0 10.0
T 15.0 15.0
Click to expand and view more

T 命令将使用之前曲线控制点的反射绘制一条新的曲线。 修改前面曲线的控制点,也会导致后面曲线的控制点被修改,从而影响整个曲线的样式。

Cubic Curves

二次曲线很好,但十分具有局限性,例如下面这个药丸形状的图形,使用二次曲线看起来就不太对(两侧很尖)。

PLAINTEXT
M 5.0 5.0
h 5.0
q 5.0 2.5 0.0 5.0
h -5.0
q -5.0 -2.5 0.0 -5.0
Z
Click to expand and view more

但如果将二次曲线换成三次曲线,看起来就顺滑多了:

PLAINTEXT
M 5.0 5.0
h 5.0
c 4.0 0.0 4.0 5.0 0.0 5.0 h -5.0
c -4.0 0.0 -4.0 -5.0 0.0 -5.0
Z
Click to expand and view more

如果能对曲线有更多的控制,就能让曲线看起来更好看。

Syntax

绘制一个三次曲线,使用 C 命令:

PLAINTEXT
C x1 y1 x2 y2 x y
Click to expand and view more

前面两对是两个控制点的位置,最后一对是曲线结束点的位置。

可以将三次曲线看成二次曲线的推广,任何二次曲线都可以通过三次曲线表示。 有趣的是,当三次曲线的两个控制点重合的时候,其对应控制点的二次曲线与其并不是同一条曲线。

Multiple Beizer Curves

就像二次曲线可以使用 T 命令连接一样,三次曲线可以使用 S 命令连接在一起。 S 的语法是第二条控制点的位置和最后曲线端点的位置:

PLAINTEXT
S x2 y2 x y
Click to expand and view more

Arcs

最后一个但同样重要的是 A arc command 弧命令。

弧命令使用下面语法绘制椭圆的一部分:

PLAINTEXT
A rx ry rotation large-arc-flag sweep-flag x y
Click to expand and view more

为了绘制出曲线,浏览器会根据当前点位置,以及上面两个位置,找到一个符合该位置的椭圆:也就是说,一个半径为 rxry 的椭圆,且保证当前点和 (x, y) 都在圆周上。

当没法找到合适椭圆的时候,椭圆不够大无法容纳所有点,会隐式的将椭圆按比例放大,使曲线仍然遵循椭圆(只是这个椭圆比指定的大)。

最后给一个绘制指纹图案的例子

PLAINTEXT
M 3.0 15.0
q 1.5 -2.0 1.5 -5.0
q 0.0 -2.0 1.5 -4.0
M 8.0 4.0
a 8.0 8.0 0.0 0.0 1.0 12.0 6.0
q 0.5 4.0 -2.0 9.0
M 13.0 21.0
q 1.5 -2.0 2.0 -5.0
M 16.0 12.0
v -1.0
a 4.0 4.0 0.0 0.0 0.0 -8.0 0.0
q 0.0 4.0 -2.5 7.0
M 8.5 20.0
q 3.0 -3.0 3.5 -9.0
Click to expand and view more

Summary

Ok, 这就是对 SVG 图像绘制的总结,下面给几个常用的示例。

HTML
<div class="ds-icon" style="font-size: 16px; width: 16px; height: 16px;">
  <svg
    width="16"
    height="16"
    viewBox="0 0 16 16"
    fill="none"
    xmlns="http://www.w3.org/2000/svg"
  >
    <path
      d="M8.27861 0.811633
      C8.81985 0.142255 9.79016 0.0422445 10.4537 0.557662
      L10.5823 0.669367
      L10.6065 0.693605
      L10.6097 0.695713
      L10.6392 0.72522
      C11.3549 1.44685 11.6336 2.49474 11.3716 3.47675
      L11.3705 3.48097
      L11.361 3.5168
      L11.36 3.51891
      L10.8889 5.2261
      C10.8796 5.26003 10.8706 5.29164 10.8626 5.32094
      C10.8934 5.32101 10.927 5.322 10.9627 5.322
      H11.9006
      C12.4263 5.322 12.783 5.31906 13.0651 5.36731
      C14.8182 5.66725 15.9851 7.34574 15.6564 9.09363
      C15.6035 9.37493 15.4769 9.70926 15.2939 10.2023
      L14.337 12.7799
      C14.1401 13.3105 13.9773 13.7518 13.8101 14.1025
      C13.6375 14.4646 13.4385 14.7794 13.1441 15.0425
      C12.9712 15.197 12.7801 15.3303 12.5751 15.4387
      C12.2259 15.6232 11.8608 15.7 11.4612 15.7359
      C11.0742 15.7705 10.6034 15.7696 10.0374 15.7696
      H4.87371
      C4.08047 15.7696 3.42922 15.7703 2.90728 15.7138
      C2.37206 15.6558 1.88985 15.5311 1.4667 15.2237
      C1.22409 15.0475 1.01072 14.834 0.834405 14.5914
      C0.52696 14.1683 0.401312 13.6861 0.343323 13.1509
      C0.286761 12.6288 0.28747 11.977 0.28747 11.1834
      V9.51411
      C0.28747 8.84785 0.281286 8.36721 0.399176 7.95656
      C0.671091 7.00941 1.41109 6.26838 2.35823 5.99645
      C2.76888 5.87855 3.24952 5.88579 3.91579 5.88579
      C4.11977 5.88579 4.14542 5.88325 4.16238 5.88053
      C4.23526 5.8687 4.30403 5.83669 4.35839 5.78674
      C4.37104 5.77511 4.38755 5.7561 4.51436 5.59494
      L8.25648 0.839033
      L8.25754 0.837979
      L8.27861 0.811633Z
      M1.69116 11.1834
      C1.69116 12.0083 1.69211 12.5712 1.73859 13.0002
      C1.78365 13.4158 1.86467 13.6222 1.96937 13.7663
      C2.05914 13.8898 2.16727 13.999 2.29079 14.0888
      C2.43495 14.1935 2.6421 14.2745 3.05797 14.3195
      C3.45891 14.363 3.97631 14.3656 4.71564 14.3659
      C4.30795 13.8053 4.06447 13.1172 4.06437 12.371
      V8.59412H5.46807
      V12.371
      C5.46832 13.4734 6.3616 14.367 7.46401 14.367
      H10.0374
      C10.6286 14.367 11.0269 14.3663 11.3368 14.3385
      C11.6339 14.3118 11.7956 14.2639 11.9196 14.1984
      C12.024 14.1431 12.1213 14.0747 12.2094 13.996
      C12.3139 13.9025 12.4151 13.7679 12.5434 13.4986
      C12.6774 13.2177 12.8162 12.8451 13.0219 12.2909
      L13.9787 9.71328
      C14.1848 9.15822 14.253 8.96737 14.278 8.83439
      C14.4617 7.85698 13.8092 6.91901 12.829 6.75098
      C12.6956 6.72816 12.4928 6.72464 11.9006 6.72464
      H10.9627
      C10.7737 6.72464 10.5693 6.72663 10.4 6.70672
      C10.2211 6.68568 9.96696 6.6303 9.74764 6.43167
      C9.64448 6.33817 9.5595 6.22616 9.49683 6.10183
      C9.36384 5.8379 9.37793 5.57905 9.40515 5.40104
      C9.43094 5.23267 9.48666 5.03623 9.53688 4.8541
      L10.0079 3.14585
      L10.0174 3.11108
      C10.1488 2.61344 10.0077 2.08344 9.64648 1.71687
      L9.60854 1.67893
      L9.55058 1.6431
      C9.48789 1.62049 9.41419 1.6382 9.36932 1.69368
      L9.35773 1.70633
      L9.35878 1.70738
      L5.61666 6.46224
      C5.51816 6.58741 5.42231 6.71336 5.30683 6.81948
      C5.05069 7.05477 4.73119 7.20945 4.3879 7.26525
      C4.23309 7.29038 4.07507 7.28843 3.91579 7.28843
      C3.1535 7.28843 2.9191 7.29576 2.74604 7.34534
      C2.26358 7.48385 1.88558 7.86087 1.74702 8.34331
      C1.69732 8.51642 1.69116 8.75116 1.69116 9.51411
      V11.1834Z"
      fill="currentColor"
    ></path>
  </svg>
</div>
Click to expand and view more
HTML
<div class="ds-icon" style="font-size: 16px; width: 16px; height: 16px;">
  <svg
    width="16"
    height="16"
    viewBox="0 0 16 16"
    fill="none"
    xmlns="http://www.w3.org/2000/svg"
  >
    <path
      d="M7.72451 15.1086C7.18929 15.7706 6.22975 15.8695 5.57357 15.3598L5.44643 15.2493L5.42247 15.2253L5.41934 15.2233L5.39016 15.1941C4.68239 14.4805 4.40679 13.4442 4.66589 12.4731L4.66693 12.4689L4.67631 12.4335L4.67735 12.4314L5.14318 10.7432C5.15243 10.7096 5.1613 10.6784 5.16923 10.6494C5.13878 10.6493 5.10558 10.6484 5.07023 10.6484H4.14274C3.62288 10.6484 3.27015 10.6513 2.9912 10.6035C1.25757 10.3069 0.103662 8.64709 0.42863 6.91861C0.480965 6.64044 0.606164 6.30981 0.787119 5.8223L1.73336 3.27328C1.92812 2.74859 2.08912 2.31215 2.25442 1.96542C2.42515 1.60731 2.62191 1.296 2.91304 1.03584C3.08408 0.883016 3.273 0.751185 3.47579 0.644009C3.82102 0.461569 4.18214 0.385575 4.57731 0.350131C4.95993 0.315849 5.42553 0.316783 5.98521 0.316783H11.0916C11.876 0.316783 12.52 0.316134 13.0362 0.372015C13.5655 0.429358 14.0423 0.552599 14.4608 0.856601C14.7007 1.03091 14.9117 1.24199 15.086 1.48187C15.3901 1.90033 15.5143 2.37716 15.5717 2.90645C15.6276 3.42275 15.6269 4.06727 15.6269 4.85209V6.5028C15.6269 7.16167 15.633 7.63697 15.5164 8.04306C15.2475 8.97969 14.5158 9.71248 13.5791 9.9814C13.173 10.098 12.6977 10.0908 12.0389 10.0908C11.8372 10.0908 11.8118 10.0933 11.795 10.096C11.723 10.1077 11.6549 10.1394 11.6012 10.1888C11.5887 10.2003 11.5724 10.2191 11.447 10.3784L7.74639 15.0815L7.74535 15.0826L7.72451 15.1086ZM14.2388 4.85209C14.2388 4.03635 14.2379 3.47971 14.1919 3.05547C14.1473 2.64449 14.0672 2.44037 13.9637 2.29785C13.8749 2.17569 13.768 2.06776 13.6458 1.97896C13.5033 1.87539 13.2984 1.7953 12.8872 1.75074C12.4907 1.70779 11.979 1.70518 11.2479 1.70489C11.6511 2.25924 11.8918 2.93974 11.8919 3.67762V7.41257H10.5038V3.67762C10.5036 2.58751 9.62023 1.70384 8.53007 1.70384H5.98521C5.40065 1.70384 5.00679 1.70449 4.70028 1.73198C4.40651 1.75836 4.24662 1.80577 4.12399 1.87058C4.02069 1.92518 3.92452 1.99283 3.8374 2.07067C3.73401 2.16312 3.634 2.29627 3.50705 2.56255C3.37462 2.84034 3.23734 3.2088 3.03393 3.75682L2.08768 6.30584C1.88395 6.85474 1.81646 7.04347 1.79172 7.17497C1.61005 8.14152 2.25533 9.06908 3.22464 9.23524C3.35654 9.25781 3.55717 9.26129 4.14274 9.26129H5.07023C5.25717 9.26129 5.4593 9.25932 5.62672 9.27901C5.80364 9.29982 6.05492 9.35458 6.27179 9.551C6.37381 9.64347 6.45784 9.75424 6.51982 9.87719C6.65133 10.1382 6.6374 10.3942 6.61048 10.5702C6.58498 10.7367 6.52988 10.931 6.48022 11.1111L6.01439 12.8003L6.00501 12.8347C5.87513 13.3268 6.01464 13.8509 6.37184 14.2134L6.40935 14.251L6.46667 14.2864C6.52866 14.3088 6.60155 14.2912 6.64591 14.2364L6.65738 14.2239L6.65633 14.2228L10.3569 9.52078C10.4543 9.397 10.5491 9.27245 10.6633 9.1675C10.9166 8.93483 11.2325 8.78186 11.572 8.72669C11.7251 8.70184 11.8814 8.70376 12.0389 8.70376C12.7927 8.70376 13.0245 8.69651 13.1956 8.64748C13.6727 8.51051 14.0465 8.13768 14.1836 7.6606C14.2327 7.48941 14.2388 7.25727 14.2388 6.5028V4.85209Z"
      fill="currentColor"
    ></path>
  </svg>
</div>
Click to expand and view more
HTML
<div class="ds-icon" style="font-size: 16px; width: 16px; height: 16px;">
  <svg
    width="16"
    height="16"
    viewBox="0 0 16 16"
    fill="none"
    xmlns="http://www.w3.org/2000/svg"
  >
    <path
      d="M14.0593 12.922L15.0976 10.1247C15.3088 9.55596 15.4144 9.27144 15.4567 9.04665C15.7349 7.56758 14.7472 6.14744 13.2638 5.89363C13.0383 5.85506 12.7349 5.85506 12.1281 5.85506H11.11C10.6615 5.85506 10.4373 5.85506 10.3034 5.73382C10.2607 5.69514 10.2255 5.64892 10.1996 5.59746C10.1183 5.43619 10.1779 5.22003 10.2971 4.78771L10.8082 2.93426L10.819 2.89463C11.0336 2.0903 10.8052 1.23251 10.219 0.641455L10.1899 0.61247L10.1692 0.592133C9.77363 0.210141 9.13565 0.249409 8.7899 0.677031L8.77192 0.699743L4.71082 5.8609C4.52971 6.09107 4.38579 6.35144 4.38579 6.64433V12.7432C4.38579 14.3601 5.6966 15.6709 7.31357 15.6709L10.1068 15.6709C11.3628 15.6709 11.9908 15.6709 12.5044 15.3996C12.6724 15.3108 12.8289 15.2019 12.9706 15.0753C13.4037 14.6883 13.6223 14.0995 14.0593 12.922Z"
      fill="currentColor"
    ></path>
    <path
      d="M2.91394 13.2114C2.91394 14.6907 4.08505 15.5536 4.08505 15.5536H2.65612C1.46334 15.5536 0.496399 14.5867 0.496399 13.3939V8.34446C0.496399 7.15168 1.46334 6.18473 2.65612 6.18473H2.91394V13.2114Z"
      fill="currentColor"
    ></path>
  </svg>
</div>
Click to expand and view more
HTML
<div class="ds-icon" style="font-size: 16px; width: 16px; height: 16px;">
  <svg
    width="16"
    height="16"
    viewBox="0 0 16 16"
    fill="none"
    xmlns="http://www.w3.org/2000/svg"
  >
    <path
      d="M1.92844 3.06818L0.888051 5.87111C0.67651 6.44103 0.570689 6.72612 0.528311 6.95137C0.249475 8.43343 1.23916 9.85643 2.72561 10.1107C2.95155 10.1494 3.25555 10.1494 3.86354 10.1494H4.88377C5.33312 10.1494 5.5578 10.1494 5.69193 10.2709C5.73473 10.3096 5.77 10.356 5.79599 10.4075C5.87745 10.5691 5.81772 10.7857 5.69827 11.2189L5.18615 13.0761L5.17529 13.1158C4.96026 13.9218 5.18916 14.7813 5.77656 15.3735L5.80574 15.4026L5.82641 15.4229C6.2228 15.8057 6.86206 15.7664 7.20852 15.3379L7.22653 15.3151L11.2958 10.1435C11.4773 9.91291 11.6215 9.65202 11.6215 9.35854V3.24741C11.6215 1.62718 10.3081 0.313722 8.68782 0.313722L5.88892 0.313721C4.63038 0.313721 4.00111 0.313721 3.48655 0.585644C3.31822 0.674603 3.16133 0.783714 3.01935 0.910574C2.58537 1.29835 2.36639 1.88831 1.92844 3.06818Z"
      fill="currentColor"
    ></path>
    <path
      d="M13.0963 2.77822C13.0963 1.29591 11.9229 0.431271 11.9229 0.431271H13.3547C14.5499 0.431271 15.5187 1.40017 15.5187 2.59535V7.65498C15.5187 8.85017 14.5499 9.81906 13.3547 9.81906H13.0963V2.77822Z"
      fill="currentColor"
    ></path>
  </svg>
</div>
Click to expand and view more

Start searching

Enter keywords to search articles

↑↓
ESC
⌘K Shortcut