第一章:SVG入门篇

SVG简介

SVG即Scalable Vector Graphics可缩放矢量图形,使用XML格式定义图形。
优点:

  • SVG与其他图片格式相比:主要优势在于可缩放的同时不会影响图片的质量。
  • 与flash相比 :SVG 最大的优势是与其他标准(比如 XSL 和 DOM)相兼容。而 Flash 则是未开源的私有技术。

SVG in HTML常用方法

使用<img>元素来嵌入SVG图像

1
<img src="http://www.w3school.com.cn/svg/rect1.svg"  width="300" />

将SVG图像作为背景图像嵌入

1
background: url('http://www.w3school.com.cn/svg/rect1.svg') no-repeat;

使用svg元素,通过代码将SVG图像嵌入到HTML代码中

1
2
3
4
5
6
7
8
<body>
<svg width="100%" height="100%">

<rect x="20" y="20" width="250" height="250"
style="fill:#fecdddd;"/>

</svg>
</body>

svg sprites

svg sprites类似于css sprites,将各个svg合并在一起。
最主要的优点就是能减少页面的加载时间,优化开发流程,以及保持页面中图片元素的一致性。
实践中我们可以把整块的svg放在head头部, 因此可以在一处地方更新svg即可,而不是让svg的代码块散落在文档的各个地方。

1
2
3
4
5
6
7
8
9
<head>
<meta charset="utf-8" />
<title>svg</title>

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="158" viewBox="0 0 32 158">
<!-- SVG等省略 -->
</svg>

</head>

在这里https://icomoon.io/app/#/select可以设置sprites,可以自己导入svg。

svg sprite

symbol+use

在head头部的svg中使用symbol元素,并使用id属性。其中symbol类似flash中的元件,可多次使用。

1
2
3
4
5
<svg id="icon-truck" width="32" height="32" viewBox="0 0 32 32" x="0" y="126">
<symbol id="truck">
<path fill="#fff" d="M24.832 11.445c-0.186-0.278-0.498-0.445-0.832-0.445h-1c-0.553 0-1 0.447-1 1v6c0 0.553 0.447 1 1 1h4c0.553 0 1-0.447 1-1v-1.5c0-0.197-0.059-0.391-0.168-0.555l-3-4.5zM27 18h-4v-6h1l3 4.5v1.5zM31.496 15.336l-4-6c-0.558-0.837-1.492-1.336-2.496-1.336h-4v-2c0-1.654-1.346-3-3-3h-15c-1.654 0-3 1.346-3 3v11c0 1.654 1.346 3 3 3v0 3c0 1.654 1.346 3 3 3h1.142c0.447 1.721 2 3 3.859 3 1.857 0 3.41-1.279 3.857-3h5.282c0.447 1.721 2 3 3.859 3 1.857 0 3.41-1.279 3.857-3h1.144c1.654 0 3-1.346 3-3v-6c0-0.594-0.174-1.17-0.504-1.664zM3 18c-0.552 0-1-0.447-1-1v-11c0-0.553 0.448-1 1-1h15c0.553 0 1 0.447 1 1v11c0 0.553-0.447 1-1 1h-15zM11.001 27c-1.105 0-2-0.896-2-2s0.895-2 2-2c1.104 0 2 0.896 2 2s-0.897 2-2 2zM24 27c-1.105 0-2-0.896-2-2s0.895-2 2-2c1.104 0 2 0.896 2 2s-0.896 2-2 2zM30 23c0 0.553-0.447 1-1 1h-1.143c-0.447-1.721-2-3-3.857-3-1.859 0-3.412 1.279-3.859 3h-5.282c-0.447-1.721-2-3-3.857-3-1.859 0-3.412 1.279-3.859 3h-1.143c-0.552 0-1-0.447-1-1v-3h13c1.654 0 3-1.346 3-3v-7h4c0.334 0 0.646 0.167 0.832 0.445l4 6c0.109 0.164 0.168 0.358 0.168 0.555v6z"></path>
</symbol>
</svg>

然后在需要用到这个元件的地方使用use元素引用元件。其中xlink:href=”#truck”相当于元件的链接,通过引用元件的id来实现。

1
<use xlink:href="#truck" x="0" y="0" />

兼容性

svg兼容性

兼容性详细情况请点击 此处

总结思考

一般在html中使用SVG有三种方法:使用<img>元素来嵌入SVG图像;将SVG图像作为背景图像嵌入;使用<svg>元素,通过代码将SVG图像嵌入到HTML代码中。
使用过程中,可通过svg sprites提高性能,通过symbol以及use元素提高文档的可维护性等。

第二章:SVG形状

矩形 <rect>

1
<rect x="20" y="20" rx="20" ry="20" width="250" height="100" style="fill:red;stroke:black; stroke-width:5;opacity:0.5"/>

解释:x为x坐标,y为y坐标;width 和 height 分别为形状的高度和宽度;rx 和 ry 属性可使矩形产生圆角。
另外,下面三个属性是文章后面会用到的,之后不会过多讲述:

  • fill 属性定义形状的填充颜色
  • stroke 属性定义图形边框的颜色
  • stroke-width 属性定义形状边框的宽度

圆形 <circle>

1
<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>

解释:cx 和 cy分别为圆点的 x 和 y 坐标;r为半径。

椭圆<ellipse>

1
<ellipse cx="300" cy="150" rx="200" ry="80" style="fill:rgb(200,100,50); stroke:rgb(0,0,100);stroke-width:2"/>

解释:cx 圆点的 x 坐标,cy 圆点的 y 坐标;rx 水平半径,ry 垂直半径。

线<line>

1
<line x1="0" y1="0" x2="300" y2="300" style="stroke:rgb(99,99,99);stroke-width:2"/>

解释:(x1,y1)为线条的开始坐标;(x2,y2)为线条的结束坐标。

折线<polyline>

1
<polyline points="0,0 0,20 20,20 20,40 40,40 40,60" style="fill:white;stroke:red;stroke-width:2"/>

解释:points 属性定义多边形每个角的 x 和 y 坐标。为了可读性,建议x与y坐标用逗号分开,每个角之间的坐标用空格分开。

多边形<polygon>

1
<polygon points="220,100 300,210 170,250" style="fill:#cccccc; stroke:#000000;stroke-width:1"/>

解释:points 属性定义多边形每个角的 x 和 y 坐标。

路径<path>

直线指令:
M = moveto
L = lineto
H = horizontal lineto
V = vertical lineto
Z = closepath
注释:以上所有命令均允许小写字母。大写表示绝对定位,小写表示相对定位。

1
2
3
<svg>
<path d="M250 150 L150 350 L350 350 Z" />
</svg>

解释:该路径开始于位置 250 150,到达位置 150 350,然后从那里开始到 350 350,最后在 250 150 关闭路径。
由于绘制路径的复杂性,建议使用 SVG 编辑器来创建复杂的图形。

svg的贝塞尔曲线

贝塞尔曲线指令:
C = curveto
S = smooth curveto
Q = quadratic Belzier curve
T = smooth quadratic Belzier curveto
贝塞尔曲线控制小工具http://dayu.pw/svgcontrol/,操控多次可加深对贝塞尔曲线的理解。

三次贝塞尔曲线控制

三次贝塞尔曲线控制

CSQT比较难记,联想记忆法“厕所切图(CSQT)”就比较容易记住了。
厕所是3D空间,所以CS是三次曲线噢,切图是平面图,所以是二次曲线,很好记。

C三次贝塞尔曲线
1
C x1 y1, x2 y2, x y (or c dx1 dy1, dx2 dy2, dx dy)

最后一个坐标(x,y)表示的是曲线的终点,另外两个坐标是控制点,(x1,y1)是起点的控制点,(x2,y2)是终点的控制点。小写指令c表示相对坐标。

S光滑三次贝塞尔曲线
1
S x2 y2, x y (or s dx2 dy2, dx dy)

之所以S命令没有x1 y1,是因为S命令跟在C命令后,x1 y1默认是C命令的第二个控制点的对称点,如下图蓝色线条所示。
光滑三次贝塞尔曲线控制

如果前面没有C命令,即S命令单独使用时,S命令画出来的是二次贝塞尔曲线,因为x1 y1和x2 y2默认是同一个控制点了。

Q二次贝塞尔曲线
1
Q x1 y1, x y (or q dx1 dy1, dx dy)
T光滑二次贝塞尔曲线
1
T x y (or t dx dy)

T命令的控制点默认是前面C命令的控制点的对称点。
光滑二次贝塞尔曲线控制

如果T命令前面没有C命令,即T命令单独使用时,T命令画出来的是直线。

总结思考

路径比基本形状更强大、更灵活。使用路径绘制复杂图形比较麻烦,但是使用它们来绘制图形的效果大多数时候很赞,一般其他基本图形是做不来的。

第三章:SVG动画


svg路径动画

DEMO:
路径动画

g元素是用于把相关元素进行组合的容器元素。animateMotion使元素沿着动作路径移动,且该路径不可见,path定义的是可见的路径。rotate=”auto”使元素移动得更加自然,会随着路径旋转一定的角度。

1
2
3
4
5
6
7
8
9
10
11
12
<svg width="1500" height="150" class="truck">
<g>
<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#truck" x="0" y="0"></use>
<animateMotion path="M0 0 C135.5 68 463.5 -8 700 29 S1000 -20 1940,70" begin="-3s" dur="10s" rotate="auto" repeatCount="indefinite"></animateMotion>
</g>
<g>
<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#truck" x="0" y="0"></use>
<animateMotion path="M0 0 C135.5 68 463.5 -8 700 29 S1000 -20 1940,70" begin="0s" dur="10s" rotate="auto" repeatCount="indefinite"></animateMotion>
</g>

<path d="M0 30 C135.5 98 463.5 22 700 59 S1000 10 1940,100" stroke="#000" stroke-width="2" fill="none" x="-1000" y="-1000" class="truck_path"></path>
</svg>

点击查看全部代码

svg路径描边动画

DEMO:
路径动画

在path等元素上必须使用stoke属性,否则动画不执行。stroke 表示描边颜色;stroke-width 表示描边的粗细;

1
2
3
4
5
<svg>
<symbol id="phone" viewBox="0 0 1024 1024">
<path fill="none" stroke="#000" stroke-width="3" d="M768 0h-512c-53.056 0-96 42.976-96 96v832c0 53.056 42.976 96 96 96h512c52.992 0 96-43.008 96-96v-832c0-53.056-43.008-96-96-96zM800 928c0 17.632-14.368 32-32 32h-512c-17.664 0-32-14.304-32-32v-64.128h576v64.128zM800 831.872h-576v-639.872h576v639.872zM800 160h-576v-64c0-17.664 14.336-32 32-32h512c17.632 0 32 14.336 32 32v64zM576 112c0 8.832-7.2 16-16 16h-96c-8.864 0-16-7.168-16-16v0c0-8.864 7.136-16 16-16h96c8.8 0 16 7.136 16 16v0zM544 911.872c0 8.8-7.2 16-16 16h-32c-8.832 0-16-7.2-16-16v0c0-8.864 7.168-16 16-16h32c8.8 0 16 7.136 16 16v0z"></path>
</symbol>
</svg>

使用CSS3 animation实现,因为内联的svg本身就是Html元素,可以通过CSS3来控制颜色等属性。
stroke-dasharray 表示虚线描边;stroke-dashoffset 表示虚线的起始偏移。

1
2
3
4
5
6
7
.device { position: absolute;top: 43%;left: 50%;margin: -200px 0 0 -200px;stroke-dasharray: 4000;stroke-dashoffset: 4000;-webkit-animation: dash 2s infinite;animation: dash 2s infinite; }
@-webkit-keyframes dash {
100% { stroke-dashoffset: 0; }
}
@keyframes dash {
100% { stroke-dashoffset: 0; }
}

点击查看全部代码

css中的clip-path

clip-path按照路径内部的尺寸进行裁剪。只有路径内的内容可见。使用方法如下:

1
2
3
.element {
clip-path: polygon(...); /* 或者其他的图形函数 */
}

1
2
3
4
5
<!-- 其他图形函数语法 -->
circle: circle(radius at x-axis y-axis)
ellipse: ellipse(x-rad y-rad at x-axis y-axis)
polygon: polygon(x-axis y-axis, x-axis y-axis, … )
inset: inset(top right bottom left round top-radius right-radius bottom-radius left-radius)

DEMO1:
clippath

利用伪元素:before和:after实现相同大小相同位置的文字,使用clip-path分别裁剪文字:

1
2
3
4
.txt { display: inline-block;position: relative;font-size: 70px;text-transform: uppercase;color: transparent; }
/* 此处省略代码 */
.txt:before { -webkit-clip-path: polygon(0 0,100% 0,100% 100%);clip-path: polygon(0 0,100% 0,100% 100%); }
.txt:after { -webkit-clip-path: polygon(0 0,0 100%,100% 100%);clip-path: polygon(0 0,0 100%,100% 100%); }

点击查看全部代码

DEMO2:
clippath

如果结合clip-path和keyframes动画,可实现相关元素按照我们的路径逐步出现的效果。clip-path可通过此工具http://www.bennettfeely.com/clippy/实现复杂的路径。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 .line { position: absolute;left: 0;top: 0;width: 28px;height: 34px;background: url(line.png) 0 0 no-repeat;-webkit-animation: moveLine .8s ease infinite;animation: moveLine .8s ease infinite; }

@-webkit-keyframes moveLine {
0% {
-webkit-clip-path: polygon(0 100%, 0 100%, 0 100%);
}
25% {
-webkit-clip-path: polygon(0 82%, 100% 81%, 100% 100%, 0 100%);
}
50% {
-webkit-clip-path: polygon(20% 0%, 80% 0%, 73% 47%, 74% 64%, 99% 100%, 0 100%, 56% 77%, 64% 58%);
}
60% {
-webkit-clip-path: polygon(50% 0%, 72% 48%, 75% 70%, 100% 100%, 0 100%, 55% 78%, 5% 68%);
}
75% {
-webkit-clip-path: polygon(28% 0, 100% 34%, 79% 100%, 0 100%, 0 0);
}
100% {
-webkit-clip-path: polygon(100% 0, 100% 100%, 0 100%, 0 0);
}
}

点击查看全部代码

总结思考

本章主要介绍svg路径动画,svg路径描边动画以及css中的clip-path,从中我们也发现了路径的强大之处,如若能在项目中灵活使用,无非给动画添加更生动的效果。

感谢您的阅读,本文由 凹凸实验室 版权所有。如若转载,请注明出处:凹凸实验室(https://aotu.io/notes/2015/11/20/svg-I-know/