\<svg>是矢量图的根元素,通过xmlns属性声明命名空间,从而告诉用户代理标记名称属于哪个XML方言。在下面的示例中,为\<svg>元素声明了宽度和高度(默认以像素为单位),其子元素\<title>可作为提示,在\<desc>中可声明一段描述性纯文本,这两个元素都不会在页面中呈现。而\<rect>是一个矩形,将被绘制到页面中。
~~~html
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100">
<title>SVG example</title>
<desc>SVG contains a rectangle</desc>
<rect width="50" height="50" fill="#F60" />
</svg>
~~~
  SVG作为一种图像格式,可以包含在\<img>元素内(如下所示)或CSS样式中(例如background-image属性)。
~~~html
<img src="demo.svg" />
~~~
## 一、坐标系统
**1)视口**
  在SVG中,有一张无限大的画布,而画布区域被称为视口(viewport)。通过\<svg>元素的width和height两个属性可定义视口的尺寸,视口的原点在其左上角。
  而在视口中,还包含一个坐标系统,由viewBox属性控制。它能包含四个数值(以逗号或空格分隔),分别是用户坐标系统的最小横坐标(x轴)和纵坐标(y轴),以及宽和高。
  下面的两个\<svg>元素,第一个采用了默认的坐标系统,第二个声明了新的坐标系统,并且宽高比相同,如图1所示,第二个矩形缩小了。
~~~html
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100">
<rect width="50" height="50" fill="#F60" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
<rect width="50" height="50" fill="#F60" />
</svg>
~~~
:-: ![](https://img.kancloud.cn/57/bb/57bbf5b7a705482a3a85b59ad197db2f_624x210.png =400x)
图 1
  接下来修改两个最小坐标(如图2所示),第一个\<svg>元素声明的最小坐标为(20,20),虽然矩形的坐标是(0,0),但是比最小坐标要小,所以就会往左上角偏移;第二个\<svg>元素声明了负数坐标,与前一个正好相反;在第三个\<svg>元素中,修改了矩形的坐标,正好在左上角。
~~~html
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="20 20 300 200">
<rect width="50" height="50" fill="#F60" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="-20 -20 300 200">
<rect width="50" height="50" fill="#F60" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="20 20 300 200">
<rect width="50" height="50" fill="#F60" x="20" y="20" />
</svg>
~~~
:-: ![](https://img.kancloud.cn/18/6a/186ac93b93efdd583e54673eec15748c_938x210.png =600x)
图 2
**2)preserveAspectRatio属性**
  当viewBox属性中声明的尺寸与视图的宽高比不一致时,可以使用preserveAspectRatio属性指定图形的缩放比例和对齐方式,语法如下,默认值是“xMidYMid meet”。
~~~html
preserveAspectRatio: <align> [<meetOrSlice>]
~~~
  其中\<align>的属性值由两个轴(x和y)以及三个位置(min、mid和max)组合而成,如表1所列。
:-: 表 1
![](https://img.kancloud.cn/23/02/230268270199434b71e3be9164fa9e05_611x516.png =400x)
  在下面的示例中,由于三个\<svg>元素宽高比是3:2,而viewBox的宽高比是3:1,因此矩形会等比缩小。对它们分别应用xMinYMin、xMidYMid和xMinYMax,效果如图3所示。
~~~html
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 100" preserveAspectRatio="xMinYMin">
<rect width="50" height="50" fill="#F60" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 100" preserveAspectRatio="xMidYMid">
<rect width="50" height="50" fill="#F60" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 100" preserveAspectRatio="xMinYMax">
<rect width="50" height="50" fill="#F60" />
</svg>
~~~
:-: ![](https://img.kancloud.cn/b7/69/b769e00c8316e827f685d4a91daa0ace_938x210.png =600x)
图 3
  注意,因为宽度正好适配,所以对于x轴的对齐方式,效果都是相同的。
  \<meetOrSlice>可控制图形的适配或裁剪,可选的值如表2所列。
:-: 表 2
![](https://img.kancloud.cn/6b/26/6b2674d0580a3628909d0fab40179a61_816x228.png =500x)
  在下面的示例中,两个矩形的高度比视口要大,对它们分别应用meet和slice,效果如图4所示,第二个矩形将整个视口给填满了。
~~~html
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 100" preserveAspectRatio="xMinYMin meet">
<rect width="150" height="150" fill="#F60" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 100" preserveAspectRatio="xMinYMin slice">
<rect width="150" height="150" fill="#F60" />
</svg>
~~~
:-: ![](https://img.kancloud.cn/64/20/64205cbbed41a94201e73d56d383e2f9_623x210.png =400x)
图 4
## 二、形状
  SVG的基本形状包括线段(line)、矩形(rect)、圆形(circle)、椭圆(ellipse)、多边形(polygon)和折线(polyline)。
**1)\<line>**
线段元素需要指定起止点的坐标,如下所示,效果如图5所示。
~~~html
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
<line x1="20" y1="100" x2="100" y2="20" stroke="black" stroke-width="2"/>
</svg>
~~~
:-: ![](https://img.kancloud.cn/6a/9f/6a9f0fa4f1197b2953c789e4fb51e4ec_310x210.png =200x)
图 5
  其中stroke和stroke-width是笔画属性,可指定笔画的颜色和宽度,相关属性如表3所列,部分属性的效果如图6所示。
:-: 表 3
![](https://img.kancloud.cn/5d/f0/5df0ac1b4b846a08bec38c2573193c1c_1274x658.png =600x)
:-: ![](https://img.kancloud.cn/ac/53/ac53503dc2ae3d16f85ceebe04d2ecbc_1550x263.png =800x)
图 6
**2)\<rect>**
  除了直角矩形之外,还可以声明圆角矩形,如下所示,效果如图7所示。
~~~html
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
<rect x="10" y="10" width="100" height="100" rx="15" ry="15" fill="#F60"/>
</svg>
~~~
:-: ![](https://img.kancloud.cn/99/54/995444681a072bfbbbebf84425ece405_315x210.png =200x)
图 7
**3)\<circle>和\<ellipse>**
  利用圆形,可非常便捷的画出圆环,效果如图8所示。将\<circle>元素的stroke-dasharray声明为圆的周长(2πR),例如半径为50,周长就是314。如果为stroke-dashoffset属性定义一个值,就能得到圆环缺失一段的效果,从而就能模拟出圆环型的进度条了。
~~~html
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
<circle cx="100" cy="100" r="50" stroke="black" stroke-width="2"
stroke-dasharray="314" stroke-dashoffset="40" fill="transparent" />
</svg>
~~~
:-: ![](https://img.kancloud.cn/9b/3b/9b3ba9ad5ffd6b921682bda01ee90450_311x210.png =200x)
图 8
  椭圆和圆形类似,只是需要声明两个方向的半径,如图9所示。
~~~html
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
<ellipse cx="100" cy="100" rx="100" ry="50" />
</svg>
~~~
:-: ![](https://img.kancloud.cn/34/a4/34a4e3fed9cdcdb35694ab268402e022_312x210.png =200x)
图 9
**4)\<polygon>**
  \<polygon>可画出任意形状的封闭图形,例如平行四边形、梯形等。在points属性中,可声明各个点的坐标,每组坐标用逗号隔开,下面绘制了一个五角星,如图10所示。
~~~html
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
<polygon points="100,0 160,180 10,60 190,60 40,180" fill="#F60"/>
</svg>
~~~
:-: ![](https://img.kancloud.cn/a5/80/a580870c4669903ee8a9dda219749312_314x210.png =200x)
图 10
**5)\<polyline>**
  折线不需要闭合,与\<polygon>元素类似,也是由points属性绘制,如下所示,得到的折线如图11所示。
~~~html
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
<polyline points="20,100 40,60 70,80 100,20" fill="none" stroke="black" />
</svg>
~~~
:-: ![](https://img.kancloud.cn/a4/f8/a4f86eb2dfa5e6b1b090ae185f62d884_311x210.png =200x)
图 11
**6)\<path>**
  上述基本形状都可以由\<path>元素来绘制,并且通过\<path>元素还可绘制出不规则的图形,例如心形,如下所示。
~~~html
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
<path d="M 10,30
A 20,20 0,0,1 50,30
A 20,20 0,0,1 90,30
Q 90,60 50,90
Q 10,60 10,30 z" />
</svg>
~~~
  其中d属性可声明一系列路径,包含多个指令,如表4所列。
:-: 表 4
![](https://img.kancloud.cn/83/34/833474f26dd87890294346c0a4284591_565x804.png =300x)
## 三、文档结构
**1)内部样式**
  SVG允许在其内部嵌入\<style>元素,如下所示,其中CDATA区段中的文本会被解析器忽略,但不影响渲染。
~~~html
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
<style>
<![CDATA[
line {
stroke: black;
stroke-width: 2;
}
]]>
</style>
<line x1="20" y1="100" x2="100" y2="20" />
</svg>
~~~
**2)\<g>**
  \<g>元素相当于一个容器,能将其所有的子元素组合在一起。应用于\<g>元素中的属性会被其子元素所继承,如下所示,两个圆的笔画颜色都是绿色,而宽度都是10,如图12所示。
~~~html
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
<g id="ring" fill="white" stroke="green" stroke-width="10">
<circle cx="80" cy="80" r="50" />
<circle cx="120" cy="120" r="50" />
</g>
</svg>
~~~
:-: ![](https://img.kancloud.cn/68/4b/684b782bd2dabe7eaeed32c856f2d9af_310x210.png =200x)
图 12
**3)\<use>**
  \<use>元素可引用其它图形,以及\<g>元素,类似于复制黏贴的功能。在下面的示例中,通过\<use>元素的xlink:href属性引用了id为ring的\<g>元素,并且将\<use>元素上声明的属性传给了\<circle>元素。
~~~html
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
<g id="ring">
<circle cx="80" cy="80" r="50" />
<circle cx="120" cy="120" r="50" />
</g>
<use x="100" y="0" fill="white" stroke="green" stroke-width="10" xlink:href="#ring" />
</svg>
~~~
  注意,当给\<use>元素定义坐标后,\<circle>元素会与其相加计算出最终的坐标,如图13所示。
:-: ![](https://img.kancloud.cn/f1/7b/f17bc474ad1c46c1d86265c276c467f0_310x210.png =200x)
图 13
**4)\<defs>**
  可将需要复用的图形抽象到\<defs>元素中,在其内部定义的图形不会直接呈现到页面中。在上面那个示例的基础上,将\<g>元素整个放置到\<defs>中,效果如图14所示,没有渲染\<g>元素中的圆。
~~~html
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
<defs>
<g id="ring">
<circle cx="80" cy="80" r="50" />
<circle cx="120" cy="120" r="50" />
</g>
</defs>
<use x="100" y="0" fill="white" stroke="green" stroke-width="10" xlink:href="#ring" />
</svg>
~~~
:-: ![](https://img.kancloud.cn/d7/c9/d7c9934ef461febf63752801eba4fd99_310x210.png =200x)
图 14
**5)\<symbol>**
  \<symbol>提供了另一种组合图形的方式,但与\<g>元素不同,它的图形不会呈现,并且它可以声明viewBox和preserveAspectRatio两个属性,如下所示。
~~~html
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100">
<symbol id="ring" viewBox="0 0 300 200">
<circle cx="80" cy="80" r="50" />
<circle cx="120" cy="120" r="50" />
</symbol>
<use fill="white" stroke="green" stroke-width="10" xlink:href="#ring" />
</svg>
~~~
**6)\<image>**
  \<use>元素可以引用SVG文件的某个部分,而\<image>元素可以引用整个SVG文件或栅格图像(如下所示),并且能控制引用文件的尺寸和preserveAspectRatio属性,效果如图15所示。
~~~html
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
<image xlink:href="img/avatar.png" width="150" />
</svg>
~~~
:-: ![](https://img.kancloud.cn/b4/3f/b43fb07a935c87474eff98b1db2f00aa_310x210.png =200x)
图 15
## 四、变形、图案和渐变
**1)变形**
  transform属性定义了一系列图形元素变形的规则,包括位移(translate)、缩放(scale)、旋转(rotate)和倾斜(skew)。注意,与CSS3中的transform属性不同,SVG中的transform属性作用的对象是坐标系统,而不是元素本身。
  translate()函数会接收两个参数,沿x轴和y轴位移坐标系统,如图16所示。
~~~html
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
<rect width="50" height="50" fill="#F60" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
<rect width="50" height="50" fill="#F60" transform="translate(50, 30)" />
</svg>
~~~
:-: ![](https://img.kancloud.cn/3b/8d/3b8d0eb5a9f5635a8e65559d6e19d013_623x210.png =400x)
图 16
  scale()函数也会接收两个参数(这点与CSS3中的scale()不同),沿x轴和y轴缩放坐标系统,如图17所示。
~~~html
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
<rect width="50" height="50" fill="#F60" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
<rect width="50" height="50" fill="#F60" transform="scale(2, 3)" />
</svg>
~~~
:-: ![](https://img.kancloud.cn/76/8d/768d9ab8294a25b6fe6684fa8e00441e_622x210.png =400x)
图 17
  rotate()函数可接收三个参数,第一个是旋转角度,另外两个是原点坐标,也就是坐标系统按照该原点旋转,如图18所示,第三个矩形指定了原点。
~~~html
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
<rect width="50" height="50" fill="#F60" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
<rect width="50" height="50" fill="#F60" transform="rotate(30)" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
<rect width="50" height="50" fill="#F60" transform="rotate(30, 50, 30)" />
</svg>
~~~
:-: ![](https://img.kancloud.cn/e1/27/e127d19b060def31e7c1bff9c7bbcf25_936x210.png =600x)
图 18
  倾斜分为两个函数:skewX()和skewY(),分别会沿着x轴和y轴倾斜,如图19所示。
~~~html
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
<rect width="50" height="50" fill="#F60" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
<rect width="50" height="50" fill="#F60" transform="skewX(30)" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="100" viewBox="0 0 300 200">
<rect width="50" height="50" fill="#F60" transform="skewY(30)" />
</svg>
~~~
:-: ![](https://img.kancloud.cn/a9/d6/a9d6d52ee2762133f70c34028fb1b5c9_938x210.png =600x)
图 19
**2)图案**
  要创建一个图案,就得使用\<pattern>元素包裹图形元素,再利用patternUnits属性确定平铺图案的方式。它有两个关键字可选,默认的objectBoundingBox会让\<pattern>元素的尺寸以百分数或0~1之间的小数表示,参照对象分别是引用\<pattern>的图形元素的宽和高。
  以下面的图案为例,它的宽和高都是10%,参照的圆形的宽高都是200,计算出的实际值就都是20,效果如图20所示。
~~~html
<svg xmlns="http://www.w3.org/2000/svg" width="250" height="200">
<defs>
<pattern id="star1" width="10%" height="10%" patternUnits="objectBoundingBox">
<circle cx="10" cy="10" r="10" />
</pattern>
</defs>
<circle cx="100" cy="100" r="100" fill="url(#star1)" />
</svg>
~~~
:-: ![](https://img.kancloud.cn/a3/b7/a3b7ed7d2d0aa03b6ff523239edb4df2_410x414.png =200x)
图 20
  另一个userSpaceOnUse会让\<pattern>元素的尺寸以绝对值表示,如下所示,因为\<pattern>元素的宽高都为25,所以图案会有空白间隙,得到的效果如图21所示。
~~~html
<svg xmlns="http://www.w3.org/2000/svg" width="250" height="200">
<defs>
<pattern id="star2" width="25" height="25" patternUnits="userSpaceOnUse">
<circle cx="10" cy="10" r="10" />
</pattern>
</defs>
<circle cx="100" cy="100" r="100" fill="url(#star2)" />
</svg>
~~~
:-: ![](https://img.kancloud.cn/6c/38/6c3898016539d121bc149b831c685566_404x414.png =200x)
图 21
  \<pattern>元素还包含另一个patternContentUnits属性,用于处理图案内部的排列方式,它的两个关键字也是objectBoundingBox和userSpaceOnUse,后者是该属性的默认值。
  objectBoundingBox会让\<pattern>中的图形元素以小数定义,如下所示。三个属性值都是0.1(不能用百分数),参照的仍然是引用\<pattern>的图形元素,计算得到的实际值都是20,效果如图22所示,每个图案只显示四分之一个圆。
~~~html
<svg xmlns="http://www.w3.org/2000/svg" width="250" height="200">
<defs>
<pattern id="star3" width="10%" height="10%" patternContentUnits="objectBoundingBox">
<circle cx=".1" cy=".1" r=".1" />
</pattern>
</defs>
<circle cx="100" cy="100" r="100" fill="url(#star3)" />
</svg>
~~~
:-: ![](https://img.kancloud.cn/08/e0/08e09d4d82582a7ae485126f775aa503_410x414.png =200x)
图 22
**3)渐变**
  \<linearGradient>元素用于绘制线性渐变,其子元素\<stop>可指定某处的色标(即渐变点),如下所示,在起点、中点和止点处声明了三种颜色,其中stop-opacity用于声明不透明度(取值范围0~1),1表示完全不透明,得到的效果如图23所示。
~~~html
<svg xmlns="http://www.w3.org/2000/svg" width="250" height="200">
<defs>
<linearGradient id="gradient">
<stop offset="0" stop-color="#F60" />
<stop offset="50%" stop-color="#CCC" stop-opacity=".5"/>
<stop offset="100%" stop-color="#FC0" />
</linearGradient>
</defs>
<rect width="200" height="100" fill="url(#gradient)" />
</svg>
~~~
:-: ![](https://img.kancloud.cn/ce/c4/cec4a1c84389b5ca4e160e5e2b4f8783_407x207.png =300x)
图 23
  如果要改变线性渐变的方向,可通过修改起点和终点的坐标实现,例如沿垂直线渐变,代码如下,得到的效果如图24所示。
~~~html
<svg xmlns="http://www.w3.org/2000/svg" width="250" height="200">
<defs>
<linearGradient id="gradientVertical" x1="0" y1="0" x2="0" y2="100%">
<stop offset="0" stop-color="#F60" />
<stop offset="50%" stop-color="#CCC" stop-opacity=".5" />
<stop offset="100%" stop-color="#FC0" />
</linearGradient>
</defs>
<rect width="200" height="100" fill="url(#gradientVertical)" />
</svg>
~~~
:-: ![](https://img.kancloud.cn/f7/d4/f7d4859b8b6abe56892ec8f2a5075cd5_410x210.png =300x)
图 24
  \<linearGradient>元素还有一个spreadMethod属性,可指定在渐变范围之外的填充方式,它有三个值可选,如下所列。
  (1)pad:默认值,用起点和终点的颜色填充。
  (2)reflect:按终点到起点,起点到终点的方式重复填充。
  (3)repeat:按起点到终点的方式重复填充。
  下面用一个示例来演示spreadMethod属性,如图25所示,从左往右,spreadMethod属性的值依次是pad、reflect和repeat。
~~~html
<svg xmlns="http://www.w3.org/2000/svg" width="800" height="200">
<defs>
<linearGradient id="spreadMethod" x1="20%" y1="30%" x2="60%" y2="70%">
<stop offset="0" stop-color="#F60" />
<stop offset="40%" stop-color="#CCC" />
<stop offset="80%" stop-color="#FC0" />
</linearGradient>
<linearGradient id="gradientPad" href="#spreadMethod" spreadMethod="pad" />
<linearGradient id="gradientReflect" href="#spreadMethod" spreadMethod="reflect" />
<linearGradient id="gradientRepeat" href="#spreadMethod" spreadMethod="repeat" />
</defs>
<rect width="200" height="100" fill="url(#gradientPad)" />
<rect width="200" height="100" fill="url(#gradientReflect)" x="210" />
<rect width="200" height="100" fill="url(#gradientRepeat)" x="420" />
</svg>
~~~
:-: ![](https://img.kancloud.cn/b0/f0/b0f03f2003aa9a78c7109e5d3b3b14aa_1247x210.png =600x)
图 25
  另外一种径向渐变由\<radialGradient>元素控制,具体可参考官方文档。
## 五、文本
**1)\<text>**
  \<text>元素用于处理SVG文件中的文本,在该元素中可修改字体样式,包括字体名称、大小、颜色、外观等。在下面的示例中,声明了四个\<text>元素,并为它们添加了各自的样式,效果如图26所示。
~~~html
<svg xmlns="http://www.w3.org/2000/svg" width="250" height="100">
<style>
.small {
font: italic 13px sans-serif;
}
.heavy {
font: bold 30px sans-serif;
}
.Rrrrr {
font: italic 40px serif;
fill: red;
}
</style>
<text x="20" y="35" class="small">My</text>
<text x="40" y="35" class="heavy">name</text>
<text x="55" y="55" class="small">is</text>
<text x="65" y="55" class="Rrrrr">Strick!</text>
</svg>
~~~
:-: ![](https://img.kancloud.cn/dd/70/dd7074267cad4f764498b783873b4128_511x210.png =300x)
图 26
**2)对齐**
  在\<text>元素中对齐文本得用text-anchor属性,它的对齐方式为起点(start)、居中(middle)和终点(end)。在下面的示例中,为了便于观察这三个关键字的行为,画了一条参考线,如图27所示。
~~~html
<svg xmlns="http://www.w3.org/2000/svg" width="120" height="150">
<path d="M60,15 L60,110 M30,40 L90,40 M30,75 L90,75 M30,110 L90,110" stroke="grey" />
<text text-anchor="start" x="60" y="40">Start</text>
<text text-anchor="middle" x="60" y="75">Middle</text>
<text text-anchor="end" x="60" y="110">End</text>
</svg>
~~~
:-: ![](https://img.kancloud.cn/af/41/af41c946aa7461c937ba83d2742790df_253x314.png =200x)
图 27
  SVG中的文本对齐与CSS中的略有不同,当起点对齐时,第一个字符会贴着参考线;当居中对齐时,文本的中间位置会被参考线贯穿;当终点对齐时,文本的最后一个字符会贴着参考线。
**3)\<tspan>**
  在\<text>元素中,通过其子元素\<tspan>可调整文本属性,从而实现一段文本呈现不同的效果,如下所示,这段文本为斜体,而\<tspan>元素中的文本被加粗并且赋予了红色(如图28所示)。
~~~html
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="100">
<style>
text {
font: italic 18px serif;
}
tspan {
font: bold 20px sans-serif;
fill: red;
}
</style>
<text x="10" y="30" class="small">
My name is
<tspan>Strick</tspan>!
</text>
</svg>
~~~
:-: ![](https://img.kancloud.cn/ea/68/ea68dbb057a4ef812577ae5aed3ca06d_410x210.png =300x)
图 28
**4)长度**
  textLength属性用于定义文本的长度,lengthAdjust属性用于设置字符间距和字形,如下所示,默认值spacing只会控制字符间距,而spacingAndGlyphs还能控制字形,如图29所示。
~~~html
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="60">
<text y="20" textLength="90%" lengthAdjust="spacing">Big text length</text>
<text y="40" textLength="90%" lengthAdjust="spacingAndGlyphs">Big text length</text>
</svg>
~~~
:-: ![](https://img.kancloud.cn/ed/07/ed07a88d0b356ab324306a99c348d231_410x133.png =300x)
图 29
**5)文本路径**
  将文本放置在\<textPath>元素中,就可让文本按任意的路径排列,而不是以往的水平或垂直排列。在下面的示例中,文本按一条螺旋曲线排列,如图30所示。
~~~html
<svg xmlns="http://www.w3.org/2000/svg" width="150" height="120">
<defs>
<path id="curve" d="M10,90 Q90,90 90,45 Q90,10 50,10 Q10,10 10,40 Q10,70 45,70 Q70,70 75,50" />
</defs>
<text>
<textPath href="#curve">
My name is Strick! What is your name?
</textPath>
</text>
</svg>
~~~
:-: ![](https://img.kancloud.cn/03/77/0377f9ccd4ef7da6266a6926e47b91bd_311x250.png =200x)
图 30
## 六、动画
**1)\<animate>**
  \<animate>是一个动画元素,它可以包含在图形元素中,多个\<animate>元素可以实现多重动画。例如将矩形先沿着水平方向,再沿着垂直方向位移,最后在位移结束后切换背景色的动画,代码如下所示,效果如图31。
~~~html
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="100">
<rect id="move" width="50" height="50" fill="#F60">
<animate attributeType="XML" dur="1s" repeatCount="1" attributeName="x"
from="0" to="50" fill="freeze" begin="1s" id="line" />
<animate attributeType="XML" dur="1s" repeatCount="1" attributeName="y"
from="0" to="30" fill="freeze" begin="2s" />
<animate attributeType="XML" dur="3s" repeatCount="indefinite" attributeName="fill"
values="#F60;#FC0;#CCC" begin="line.end" />
</rect>
</svg>
~~~
:-: ![](https://img.kancloud.cn/8d/94/8d94029ae728144159223c677724f6e5_428x220.gif =300x)
图 31
  \<animate>元素包含多个动画属性,此处只使用了其中的几个,具体说明如下,其中fill="freeze"是指动画结束后保持最后的动作。
  (1)attributeName:执行动画的属性。
  (2)attributeType:属性类型,可选值包括XML和CSS。
  (3)from:属性的起始值。
  (4)to:属性的结束值。
  (5)dur:动画持续时间。
  (6)repeatCount:动画执行次数,可以是有限次的整数,也可以是无限次的indefinite。
  (7)begin:动画开始时机,可以是秒数,也可以是某个动作,例如上面第一个动画结束后执行颜色的切换。
  \<set>元素是对\<animate>元素的补充,可为那些不能过渡的属性提供动画,例如在某个时刻显示文本,如下所示,点击矩形可显示“change color”。
~~~html
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="100">
<!--省略矩形代码-->
<text x="100" y="20" text-anchor="middle" style="display:none">
<set attributeName="display" attributeType="CSS" to="block" begin="move.click" dur="1s" fill="freeze" />
change color
</text>
</svg>
~~~
**2)\<animateTransform>**
  对于transform属性的动画,得用\<animateTransform>元素完成。下面的示例演示了旋转矩形(如图32所示),其中type属性用于指定变形的动作,可选的值有translate、scale、rotate、skewX和skewY。
~~~html
<svg xmlns="http://www.w3.org/2000/svg" width="180" height="160">
<rect id="move" width="50" height="50" fill="#F60" x="80" y="80">
<animateTransform attributeName="transform" attributeType="XML" type="rotate"
from="0 80 80" to="360 80 80" dur="5s" repeatCount="indefinite" />
</rect>
</svg>
~~~
:-: ![](https://img.kancloud.cn/4d/59/4d59ccaf789351889db3af52c07758bb_383x341.gif =200x)
图 32
**3)\<animateMotion>**
  \<animateMotion>元素可让图形沿着任意路径运动,无论是直线还是曲线,都能实现。在下面的示例中,橙色矩形会沿着S型曲线来回运动,如图33所示。
~~~html
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="100">
<path fill="none" stroke="#000"
d="M20,50 C20,-50 180,150 180,50 C180-50 20,150 20,50 z" />
<rect width="20" height="10" fill="#F60">
<animateMotion dur="10s" repeatCount="indefinite"
path="M20,50 C20,-50 180,150 180,50 C180-50 20,150 20,50 z" />
</rect>
</svg>
~~~
:-: ![](https://img.kancloud.cn/bc/b3/bcb3b031f74c47fda7a2fd677ae419d4_424x223.gif =300x)
图 33
  如果要让矩形始终沿着平行于曲线的方向运动,那么可以将rotate属性设为auto,如图34所示。
~~~html
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="100">
<path fill="none" stroke="#000"
d="M20,50 C20,-50 180,150 180,50 C180-50 20,150 20,50 z" />
<rect width="20" height="10" fill="#F60">
<animateMotion dur="10s" repeatCount="indefinite" rotate="auto"
path="M20,50 C20,-50 180,150 180,50 C180-50 20,150 20,50 z" />
</rect>
</svg>
~~~
:-: ![](https://img.kancloud.cn/66/48/66484a22ca04d36d3db45941038f623b_422x223.gif =300x)
图 34
*****
> 原文出处:
[博客园-HTML躬行记](https://www.cnblogs.com/strick/category/1770829.html)
[知乎专栏-HTML躬行记](https://zhuanlan.zhihu.com/c_1250826149041238016)
已建立一个微信前端交流群,如要进群,请先加微信号freedom20180706或扫描下面的二维码,请求中需注明“看云加群”,在通过请求后就会把你拉进来。还搜集整理了一套[面试资料](https://github.com/pwstrick/daily),欢迎阅读。
![](https://box.kancloud.cn/2e1f8ecf9512ecdd2fcaae8250e7d48a_430x430.jpg =200x200)
推荐一款前端监控脚本:[shin-monitor](https://github.com/pwstrick/shin-monitor),不仅能监控前端的错误、通信、打印等行为,还能计算各类性能参数,包括 FMP、LCP、FP 等。
- ES6
- 1、let和const
- 2、扩展运算符和剩余参数
- 3、解构
- 4、模板字面量
- 5、对象字面量的扩展
- 6、Symbol
- 7、代码模块化
- 8、数字
- 9、字符串
- 10、正则表达式
- 11、对象
- 12、数组
- 13、类型化数组
- 14、函数
- 15、箭头函数和尾调用优化
- 16、Set
- 17、Map
- 18、迭代器
- 19、生成器
- 20、类
- 21、类的继承
- 22、Promise
- 23、Promise的静态方法和应用
- 24、代理和反射
- HTML
- 1、SVG
- 2、WebRTC基础实践
- 3、WebRTC视频通话
- 4、Web音视频基础
- CSS进阶
- 1、CSS基础拾遗
- 2、伪类和伪元素
- 3、CSS属性拾遗
- 4、浮动形状
- 5、渐变
- 6、滤镜
- 7、合成
- 8、裁剪和遮罩
- 9、网格布局
- 10、CSS方法论
- 11、管理后台响应式改造
- React
- 1、函数式编程
- 2、JSX
- 3、组件
- 4、生命周期
- 5、React和DOM
- 6、事件
- 7、表单
- 8、样式
- 9、组件通信
- 10、高阶组件
- 11、Redux基础
- 12、Redux中间件
- 13、React Router
- 14、测试框架
- 15、React Hooks
- 16、React源码分析
- 利器
- 1、npm
- 2、Babel
- 3、webpack基础
- 4、webpack进阶
- 5、Git
- 6、Fiddler
- 7、自制脚手架
- 8、VSCode插件研发
- 9、WebView中的页面调试方法
- Vue.js
- 1、数据绑定
- 2、指令
- 3、样式和表单
- 4、组件
- 5、组件通信
- 6、内容分发
- 7、渲染函数和JSX
- 8、Vue Router
- 9、Vuex
- TypeScript
- 1、数据类型
- 2、接口
- 3、类
- 4、泛型
- 5、类型兼容性
- 6、高级类型
- 7、命名空间
- 8、装饰器
- Node.js
- 1、Buffer、流和EventEmitter
- 2、文件系统和网络
- 3、命令行工具
- 4、自建前端监控系统
- 5、定时任务的调试
- 6、自制短链系统
- 7、定时任务的进化史
- 8、通用接口
- 9、微前端实践
- 10、接口日志查询
- 11、E2E测试
- 12、BFF
- 13、MySQL归档
- 14、压力测试
- 15、活动规则引擎
- 16、活动配置化
- 17、UmiJS版本升级
- 18、半吊子的可视化搭建系统
- 19、KOA源码分析(上)
- 20、KOA源码分析(下)
- 21、花10分钟入门Node.js
- 22、Node环境升级日志
- 23、Worker threads
- 24、低代码
- 25、Web自动化测试
- 26、接口拦截和页面回放实验
- 27、接口管理
- 28、Cypress自动化测试实践
- 29、基于Electron的开播助手
- Node.js精进
- 1、模块化
- 2、异步编程
- 3、流
- 4、事件触发器
- 5、HTTP
- 6、文件
- 7、日志
- 8、错误处理
- 9、性能监控(上)
- 10、性能监控(下)
- 11、Socket.IO
- 12、ElasticSearch
- 监控系统
- 1、SDK
- 2、存储和分析
- 3、性能监控
- 4、内存泄漏
- 5、小程序
- 6、较长的白屏时间
- 7、页面奔溃
- 8、shin-monitor源码分析
- 前端性能精进
- 1、优化方法论之测量
- 2、优化方法论之分析
- 3、浏览器之图像
- 4、浏览器之呈现
- 5、浏览器之JavaScript
- 6、网络
- 7、构建
- 前端体验优化
- 1、概述
- 2、基建
- 3、后端
- 4、数据
- 5、后台
- Web优化
- 1、CSS优化
- 2、JavaScript优化
- 3、图像和网络
- 4、用户体验和工具
- 5、网站优化
- 6、优化闭环实践
- 数据结构与算法
- 1、链表
- 2、栈、队列、散列表和位运算
- 3、二叉树
- 4、二分查找
- 5、回溯算法
- 6、贪心算法
- 7、分治算法
- 8、动态规划
- 程序员之路
- 大学
- 2011年
- 2012年
- 2013年
- 2014年
- 项目反思
- 前端基础学习分享
- 2015年
- 再一次项目反思
- 然并卵
- PC网站CSS分享
- 2016年
- 制造自己的榫卯
- PrimusUI
- 2017年
- 工匠精神
- 2018年
- 2019年
- 前端学习之路分享
- 2020年
- 2021年
- 2022年
- 2023年
- 日志
- 2020