0%

SVG实现logo及点击动态效果

效果展示

实现原理

1、路径绘图

图标主要是用svg的path属性,首先先了解一下,path有哪些命令。

命令 属性
M 移动到某个点
L 画直线
H 水平线
V 垂直线
C 二次赛贝尔曲线
S 平滑二次赛贝尔曲线
Q 三次赛贝尔曲线
T 平滑赛贝尔曲线
A 弧线
Z 结束点
2、简单绘图

现在先简单的绘制一个屋顶三角形,图标大小为45 X 45。

1
2
3
4
5
6
7
<svg width="45" height="45" class="path">
<path d="M 1 22
L 22.5 1
L 44 22
Z">
</path>
</svg>

3、添加圆角

因为图标所有线条的连接点都是圆滑的曲线,只是单纯的用坐标绘制会得到如上图所示生硬的结果,于是二次赛贝尔曲线就出现了。利用三次赛贝尔曲线的原理,以转折点的左边坐标点为起始点,然后以转折点为控制点,转折点右边坐标点为终点。先拿顶角为例,顶角坐标为 (22.5,1),圆角的实现为:

起始点 (21.5 2)、控制点(22.5,1)、终点(23.5,2)

1
2
3
4
5
6
7
<svg width="45" height="45" class="path">
<path d="M 1 22
L 21.5 2 Q 22.5 1 23.5 2
L 44 22
Z">
</path>
</svg>

4、画icon

有了上面的基础,我们只需要把icon的每个坐标点都通过三次赛贝尔曲线描绘,就可以得到一个完整的小房子。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<svg width="45" height="45" class="path">
<path d="M 25 3 Q 22.5 1 20 3
L 2 18 Q 1 22 5 22
L 7 20
L 7 35 Q 7 43 12 43
L 17 43 Q 19 43 19 41
L 19 31 Q 19 29 20 29
L 25 29 Q 26 29 26 31
L 26 41 Q 26 43 28 43
L 33 43 Q 38 43 38 35
L 38 20
L 40 22 Q 44 22 43 18 Z"
stroke="#333"
stroke-width="1.5"
fill="none">
</path>
<path d="M 23.5 25 Q 22.5 25 21.5 25
L 19 25 Q 18 25 18 24
L 18 21
L 18 19 Q 18 18 19 18
L 20 18 Q 21 18 22 18
L 20 18 Q 21 18 22 18
L 23 18 Q 24 18 24 18
L 23 18 Q 24 18 24 18
L 26 18 Q 27 18 27 19
L 27 21
L 27 24 Q 27 25 26 25
Z"
fill="#0BCCB0"
stroke="none"></path>
</svg>
5、添加动画

动画的原理是改变SVG的路径,变成另一个图形,前提是这两个图形的坐标值数量必须一样。因此为了正方形能够转换变成房子,将正方形的坐标拆解成多个。利用css的animation动画,实现路径变化的动态效果。伪代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
html:
<label>
<input type="checkbox" id="home" />
<svg width="45px" height="45px">
<defs>
<linearGradient id="grad1" x1="0%" y1="0%" x2="0" y2="100%">
<stop offset="0%" style="stop-color:#67F1DD;stop-opacity:1" />
<stop offset="100%" style="stop-color:#15CCB2;stop-opacity:1" />
</linearGradient>
</defs>
<path class="background"></path>
<path class="border"></path>
</svg>
</label>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#home{
display: none;
}
.background{
fill: url(#grad1);
animation: toSmall .5s linear forwards;
}
.border{
fill: none;
stroke: #333;
stroke-width: 1.5;
animation: fade-in .5s linear forwards;
opacity: 0;
d: path('M 25 3 Q 22.5 1 20 3 L 2 18 Q 1 22 5 22 L 7 20 L 7 35 Q 7 43 12 43 L 17 43 Q 19 43 19 41 L 19 31 Q 19 29 20 29 L 25 29 Q 26 29 26 31 L 26 41 Q 26 43 28 43 L 33 43 Q 38 43 38 35 L 38 20 L 40 22 Q 44 22 43 18 Z');
}
#home:checked + svg .background {
stroke-width: 1.5;
stroke: url(#grad1);
animation: bigger .5s linear forwards;
}
#home:checked + svg .border {
opacity: 1;
animation: fade-out .3s linear forwards;
}
@keyframes bigger {
0% {
d: path('M 23.5 18 Q 22.5 18 21.5 18 L 19 18 Q 18 18 18 19 L 18 21 L 18 24 Q 18 25 19 25 L 20 25 Q 21 25 22 25 L 20 25 Q 21 25 22 25 L 23 25 Q 24 25 24 25 L 23 25 Q 24 25 24 25 L 26 25 Q 27 25 27 24 L 27 21 L 27 19 Q 27 18 26 18 Z');
}
50% {
d: path('M 25 3 Q 22.5 1 20 3 L 2 18 Q 1 22 5 22 L 7 20 L 7 35 Q 7 43 12 43 L 17 43 Q 19 43 19 43 L 19 43 Q 19 43 20 43 L 25 43 Q 26 43 26 43 L 26 43 Q 26 43 28 43 L 33 43 Q 38 43 38 35 L 38 20 L 40 22 Q 44 22 43 18 Z');
}

100% {
d: path('M 25 3 Q 22.5 1 20 3 L 2 18 Q 1 22 5 22 L 7 20 L 7 35 Q 7 43 12 43 L 17 43 Q 19 43 19 41 L 19 31 Q 19 29 20 29 L 25 29 Q 26 29 26 31 L 26 41 Q 26 43 28 43 L 33 43 Q 38 43 38 35 L 38 20 L 40 22 Q 44 22 43 18 Z');
}
}
@keyframes toSmall{
0%{
d: path('M 25 3 Q 22.5 1 20 3 L 2 18 Q 1 22 5 22 L 7 20 L 7 35 Q 7 43 12 43 L 17 43 Q 19 43 19 41 L 19 31 Q 19 29 20 29 L 25 29 Q 26 29 26 31 L 26 41 Q 26 43 28 43 L 33 43 Q 38 43 38 35 L 38 20 L 40 22 Q 44 22 43 18 Z');
}
50%{
d: path('M 22.5 22.5 Q 22.5 22.5 22.5 22.5 L 22.5 22.5 Q 22.5 22.5 22.5 22.5 L 22.5 22.5 L 22.5 22.5 Q 22.5 22.5 22.5 22.5 L 22.5 22.5 Q 22.5 22.5 22.5 22.5 L 22.5 22.5 Q 22.5 22.5 22.5 22.5 L 22.5 22.5 Q 22.5 22.5 22.5 22.5 L 22.5 22.5 Q 22.5 22.5 22.5 22.5 L 22.5 22.5 Q 22.5 22.5 22.5 22.5 L 22.5 22.5 L 22.5 22.5 Q 22.5 22.5 22.5 22.5 Z');
}
100%{
d: path('M 23.5 18 Q 22.5 18 21.5 18 L 19 18 Q 18 18 18 19 L 18 21 L 18 24 Q 18 25 19 25 L 20 25 Q 21 25 22 25 L 20 25 Q 21 25 22 25 L 23 25 Q 24 25 24 25 L 23 25 Q 24 25 24 25 L 26 25 Q 27 25 27 24 L 27 21 L 27 19 Q 27 18 26 18 Z');
}
}
@keyframes fade-in{
from{opacity: 0;}
to{ opacity: 1;}
}
@keyframes fade-out{
from{opacity: 1;}
to{opacity: 0;}
}
-------------The End-------------
坚持原创技术分享,您的支持将鼓励我继续创作!