ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
&emsp;&emsp;\<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> ~~~ &emsp;&emsp;SVG作为一种图像格式,可以包含在\<img>元素内(如下所示)或CSS样式中(例如background-image属性)。 ~~~html <img src="demo.svg" /> ~~~ ## 一、坐标系统 **1)视口** &emsp;&emsp;在SVG中,有一张无限大的画布,而画布区域被称为视口(viewport)。通过\<svg>元素的width和height两个属性可定义视口的尺寸,视口的原点在其左上角。 &emsp;&emsp;而在视口中,还包含一个坐标系统,由viewBox属性控制。它能包含四个数值(以逗号或空格分隔),分别是用户坐标系统的最小横坐标(x轴)和纵坐标(y轴),以及宽和高。 &emsp;&emsp;下面的两个\<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 &emsp;&emsp;接下来修改两个最小坐标(如图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属性** &emsp;&emsp;当viewBox属性中声明的尺寸与视图的宽高比不一致时,可以使用preserveAspectRatio属性指定图形的缩放比例和对齐方式,语法如下,默认值是“xMidYMid meet”。 ~~~html preserveAspectRatio: <align> [<meetOrSlice>] ~~~ &emsp;&emsp;其中\<align>的属性值由两个轴(x和y)以及三个位置(min、mid和max)组合而成,如表1所列。 :-: 表 1 ![](https://img.kancloud.cn/23/02/230268270199434b71e3be9164fa9e05_611x516.png =400x) &emsp;&emsp;在下面的示例中,由于三个\<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 &emsp;&emsp;注意,因为宽度正好适配,所以对于x轴的对齐方式,效果都是相同的。 &emsp;&emsp;\<meetOrSlice>可控制图形的适配或裁剪,可选的值如表2所列。 :-: 表 2 ![](https://img.kancloud.cn/6b/26/6b2674d0580a3628909d0fab40179a61_816x228.png =500x) &emsp;&emsp;在下面的示例中,两个矩形的高度比视口要大,对它们分别应用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 ## 二、形状 &emsp;&emsp;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 &emsp;&emsp;其中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>** &emsp;&emsp;除了直角矩形之外,还可以声明圆角矩形,如下所示,效果如图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>** &emsp;&emsp;利用圆形,可非常便捷的画出圆环,效果如图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 &emsp;&emsp;椭圆和圆形类似,只是需要声明两个方向的半径,如图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>** &emsp;&emsp;\<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>** &emsp;&emsp;折线不需要闭合,与\<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>** &emsp;&emsp;上述基本形状都可以由\<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> ~~~ &emsp;&emsp;其中d属性可声明一系列路径,包含多个指令,如表4所列。 :-: 表 4 ![](https://img.kancloud.cn/83/34/833474f26dd87890294346c0a4284591_565x804.png =300x) ## 三、文档结构 **1)内部样式** &emsp;&emsp;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>** &emsp;&emsp;\<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>** &emsp;&emsp;\<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> ~~~ &emsp;&emsp;注意,当给\<use>元素定义坐标后,\<circle>元素会与其相加计算出最终的坐标,如图13所示。 :-: ![](https://img.kancloud.cn/f1/7b/f17bc474ad1c46c1d86265c276c467f0_310x210.png =200x) 图 13 **4)\<defs>** &emsp;&emsp;可将需要复用的图形抽象到\<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>** &emsp;&emsp;\<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>** &emsp;&emsp;\<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)变形** &emsp;&emsp;transform属性定义了一系列图形元素变形的规则,包括位移(translate)、缩放(scale)、旋转(rotate)和倾斜(skew)。注意,与CSS3中的transform属性不同,SVG中的transform属性作用的对象是坐标系统,而不是元素本身。 &emsp;&emsp;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 &emsp;&emsp;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 &emsp;&emsp;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 &emsp;&emsp;倾斜分为两个函数: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)图案** &emsp;&emsp;要创建一个图案,就得使用\<pattern>元素包裹图形元素,再利用patternUnits属性确定平铺图案的方式。它有两个关键字可选,默认的objectBoundingBox会让\<pattern>元素的尺寸以百分数或0~1之间的小数表示,参照对象分别是引用\<pattern>的图形元素的宽和高。 &emsp;&emsp;以下面的图案为例,它的宽和高都是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 &emsp;&emsp;另一个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 &emsp;&emsp;\<pattern>元素还包含另一个patternContentUnits属性,用于处理图案内部的排列方式,它的两个关键字也是objectBoundingBox和userSpaceOnUse,后者是该属性的默认值。 &emsp;&emsp;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)渐变** &emsp;&emsp;\<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 &emsp;&emsp;如果要改变线性渐变的方向,可通过修改起点和终点的坐标实现,例如沿垂直线渐变,代码如下,得到的效果如图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 &emsp;&emsp;\<linearGradient>元素还有一个spreadMethod属性,可指定在渐变范围之外的填充方式,它有三个值可选,如下所列。 &emsp;&emsp;(1)pad:默认值,用起点和终点的颜色填充。 &emsp;&emsp;(2)reflect:按终点到起点,起点到终点的方式重复填充。 &emsp;&emsp;(3)repeat:按起点到终点的方式重复填充。 &emsp;&emsp;下面用一个示例来演示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 &emsp;&emsp;另外一种径向渐变由\<radialGradient>元素控制,具体可参考官方文档。 ## 五、文本 **1)\<text>** &emsp;&emsp;\<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)对齐** &emsp;&emsp;在\<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 &emsp;&emsp;SVG中的文本对齐与CSS中的略有不同,当起点对齐时,第一个字符会贴着参考线;当居中对齐时,文本的中间位置会被参考线贯穿;当终点对齐时,文本的最后一个字符会贴着参考线。 **3)\<tspan>** &emsp;&emsp;在\<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)长度** &emsp;&emsp;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)文本路径** &emsp;&emsp;将文本放置在\<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>** &emsp;&emsp;\<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 &emsp;&emsp;\<animate>元素包含多个动画属性,此处只使用了其中的几个,具体说明如下,其中fill="freeze"是指动画结束后保持最后的动作。 &emsp;&emsp;(1)attributeName:执行动画的属性。 &emsp;&emsp;(2)attributeType:属性类型,可选值包括XML和CSS。 &emsp;&emsp;(3)from:属性的起始值。 &emsp;&emsp;(4)to:属性的结束值。 &emsp;&emsp;(5)dur:动画持续时间。 &emsp;&emsp;(6)repeatCount:动画执行次数,可以是有限次的整数,也可以是无限次的indefinite。 &emsp;&emsp;(7)begin:动画开始时机,可以是秒数,也可以是某个动作,例如上面第一个动画结束后执行颜色的切换。 &emsp;&emsp;\<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>** &emsp;&emsp;对于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>** &emsp;&emsp;\<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 &emsp;&emsp;如果要让矩形始终沿着平行于曲线的方向运动,那么可以将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 等。