旋转式侧边栏 Rotating-Nav-Animation
1. 概述
该项目本体模拟了一篇博文, 侧边栏可通过左上角的 $1/4$ 圆按钮唤起. 唤起侧边栏后整个页面会逆时针旋转, 而左下角会飞出页面导航.
本项目中将涉及如下知识点:
rotate
动画的使用- 从外部导入
fontAwesome
字体
效果:
2. 结构和切图
网页的基本结构如下:
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
<body>
<div class="container">
<div class="circle-container">
<div class="circle">
<button id="close">
<i class="fas fa-times"></i>
</button>
<button id="open">
<i class="fas fa-bars"></i>
</button>
</div>
</div>
<div class="content">
<!---Your Article Appears Here--->
</div>
</div>
<nav>
<ul>
<li><i class="fas fa-home"></i><a href="#"> Home </a></li>
<li><i class="fas fa-user-alt"></i><a href="#"> About </a></li>
<li><i class="fas fa-envelope"></i><a href="#"> Contact </a></li>
</ul>
</nav>
<script>
</script>
</body>
总体上网页由三个部分组成: 一个竖向导航栏, 一个包含文章主体和 $1/4$ 圆形按键的 div
容器.
3. 编写 CSS
样式
我们此处只考虑涉及页面切换动画和竖向导航栏的核心 CSS
:
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
.container{
background-color: #fafafa;
transform-origin: top left;
transition: transform 0.3s ease;
width: 100vw;
min-height: 100vh;
padding: 50px;
}
.container.show-nav{
transform: rotate(-20deg);
}
.circle-container{
position: fixed;
top: -100px;
left: -100px;
}
.circle{
background-color: #ff7979;
height: 200px;
width: 200px;
border-radius: 50%;
position: relative;
transition: transform 0.3s linear;
}
.container.show-nav .circle{
transform: rotate(-70deg);
}
.circle button {
cursor: pointer;
position: absolute;
top: 45%;
left: 50%;
height: 100px;
background: transparent;
border: 0;
font-size: 26px;
color: #fff;
}
.circle button:focus {
outline: none;
}
.circle button#open {
left: 60%;
}
.circle button#close {
top: 60%;
transform: rotate(90deg);
transform-origin: top left;
}
.container.show-nav + nav li {
transform: translateX(0);
transition-delay: 0.2s;
}
此处涉及的核心 CSS
语句是 transform: rotate(...deg)
和 transform-origin: top left
: 前者控制元素 逆时针 旋转的角度, 后者控制元素旋转中心的位置. 在本项目中, 我们统一规定元素的旋转中心为 页面左上角.
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
nav {
position: fixed;
bottom: 40px;
left: 0;
z-index: 100;
}
nav ul {
list-style-type: none;
padding-left: 30px;
}
nav ul li {
text-transform: uppercase;
color: #fff;
margin: 40px 0;
transform: translateX(-100%);
transition: transform 0.3s ease-in;
}
nav ul li i {
font-size: 20px;
margin-right: 10px;
}
nav ul li+li {
margin-left: 15px;
transform: translateX(-150%);
}
nav ul li + li + li {
margin-left: 30px;
transform: translateX(-200%);
}
nav a{
color: #fafafa;
text-decoration: none;
transition: all 0.3s;
}
nav a:hover{
color: #ff7979;
font-weight: bold;
}
我们再次回顾 CSS
选择器的 (部分) 选择规则:
选择器 | 例子 | 解释 |
---|---|---|
.class1 .class2 |
.name1 .name2 |
选择作为类名 name1 元素后代的所有类名 name2 元素 |
.class1.class2 |
.name1.name2 |
选择 class 属性中同时有 name1 和 name2 的所有元素 |
element+element |
div + p |
选择紧跟 <div> 元素的首个 <p> 元素 |
不难理解, 上述涉及竖直导航栏的 CSS
样式表分别选择了三行链接并定义了它们的不同样式 (主要的不同在其位置上).
我们可以使用
1
2
3
4
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css"
integrity="sha512-1PKOgIY59xJ8Co8+NE6FZ+LOAZKjy+KY8iq0G4B3CyeY6wYHN3yt9PW0XpSriVlkMXe40PTKnXrLnZ9+fkDaog=="
crossorigin="anonymous" />
引入 FontAwesome
字体, 并在 <i/>
标签中指定 className
使用不同的图标.
完整的 CSS
样式表如下:
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
<style>
* {
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
background-color: #323232;
color: #222;
overflow-x: hidden;
margin: 0;
}
.container{
background-color: #fafafa;
transform-origin: top left;
transition: transform 0.3s ease;
width: 100vw;
min-height: 100vh;
padding: 50px;
}
.container.show-nav{
transform: rotate(-20deg);
}
.circle-container{
position: fixed;
top: -100px;
left: -100px;
}
.circle{
background-color: #ff7979;
height: 200px;
width: 200px;
border-radius: 50%;
position: relative;
transition: transform 0.3s linear;
}
.container.show-nav .circle{
transform: rotate(-70deg);
}
.circle button {
cursor: pointer;
position: absolute;
top: 45%;
left: 50%;
height: 100px;
background: transparent;
border: 0;
font-size: 26px;
color: #fff;
}
.circle button:focus {
outline: none;
}
.circle button#open {
left: 60%;
}
.circle button#close {
top: 60%;
transform: rotate(90deg);
transform-origin: top left;
}
.container.show-nav + nav li {
transform: translateX(0);
transition-delay: 0.2s;
}
nav {
position: fixed;
bottom: 40px;
left: 0;
z-index: 100;
}
nav ul {
list-style-type: none;
padding-left: 30px;
}
nav ul li {
text-transform: uppercase;
color: #fff;
margin: 40px 0;
transform: translateX(-100%);
transition: transform 0.3s ease-in;
}
nav ul li i {
font-size: 20px;
margin-right: 10px;
}
nav ul li+li {
margin-left: 15px;
transform: translateX(-150%);
}
nav ul li + li + li {
margin-left: 30px;
transform: translateX(-200%);
}
nav a{
color: #fafafa;
text-decoration: none;
transition: all 0.3s;
}
nav a:hover{
color: #ff7979;
font-weight: bold;
}
.content img{
max-width: 100%;
}
.content {
max-width: 1000px;
margin: 50px auto;
}
.content h1 {
margin: 0;
}
.content small {
color: #555;
font-style: italic;
}
.content p {
color: #333;
line-height: 1.5;
}
</style>
4. JavaScript
最后编写 JavaScript
检查 $1/4$ 圆形按钮的点击状态并修改其 className
以实现旋转切换动画:
1
2
3
4
5
6
const open = document.getElementById('open')
const close = document.getElementById('close')
const container = document.querySelector('.container')
open.addEventListener('click', () => container.classList.add('show-nav'))
close.addEventListener('click', () => container.classList.remove('show-nav'))
最后, 完整的网页演示可见 此处