百万特效师-炫酷的登录动画

百万特效师之炫酷的登录动画-001

百万特效师系列,不多说,上效果

效果演示

实际效果地址

使用到的技术栈

  1. React
  2. tailwindCSS
  3. animejs(也可以手写动画)

源码

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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
import './LoginAnimate.less'
import anime from 'animejs/lib/anime.es.js'
import { useRef } from 'react'

const LoginAnimate: React.FC = () => {
const containerRef = useRef<HTMLDivElement>(null)
const animation = (type: number) => {
console.log(containerRef.current?.clientWidth)
const width = containerRef.current?.clientWidth || 0
// 隐藏登录 显示注册
if (type == 1) {
anime({
targets: '.login-container-1 .box-sign-anime1',
translateX: {
value: width / 4,
duration: 1000
},
opacity: {
value: 0,
delay: 300,
duration: 300
},
easing: 'easeInOutQuad'
})
anime({
targets: '.login-container-1 .box-sign-anime2',
translateX: {
value: width / 4,
duration: 1000
},
opacity: {
value: 1,
delay: 500,
duration: 300
},
zIndex: {
value: 2,
duration: 1
},
easing: 'easeInOutQuad'
})
anime({
targets: '.login-container-1 .box-desc-anime1',
translateX: -width / 2,
borderTopLeftRadius: ['25%', '0%'],
borderBottomLeftRadius: ['25%', '0%'],
borderTopRightRadius: ['0%', '25%'],
borderBottomRightRadius: ['0%', '25%'],
easing: 'easeInOutQuad',
duration: 1000,
zIndex: {
value: 4,
duration: 1
}
})
anime({
targets: '.login-container-1 .box-desc-son1',
visibility: 'hidden',
opacity: 0,
easing: 'easeInOutQuad',
duration: 800
})
anime({
targets: '.login-container-1 .box-desc-son2',
visibility: 'visible',
opacity: 1,
easing: 'easeInOutQuad',
zIndex: 3,
duration: 800,
delay: 200
})
} else {
anime({
targets: '.login-container-1 .box-sign-anime1',
translateX: {
value: 0,
duration: 1000,
},
opacity: {
value: 1,
delay: 300,
duration: 300
},
easing: 'easeInOutQuad'
})
anime({
targets: '.login-container-1 .box-sign-anime2',
translateX: {
value: 0,
duration: 1000
},
opacity: {
value: 0,
delay: 500,
duration: 300
},
zIndex: {
value: 1,
duration: 1
},
easing: 'easeInOutQuad'
})
anime({
targets: '.login-container-1 .box-desc-anime1',
translateX: 0,
borderTopLeftRadius: ['0%', '25%'],
borderBottomLeftRadius: ['0%', '25%'],
borderTopRightRadius: ['25%', '0%'],
borderBottomRightRadius: ['25%', '0%'],
easing: 'easeInOutQuad',
duration: 1000,
zIndex: {
value: 2,
duration: 1
}
})
anime({
targets: '.login-container-1 .box-desc-son2',
visibility: 'hidden',
opacity: 0,
easing: 'easeInOutQuad',
duration: 800,
zIndex: 1
})
anime({
targets: '.login-container-1 .box-desc-son1',
visibility: 'visible',
opacity: 1,
easing: 'easeInOutQuad',
zIndex: 2,
duration: 800,
delay: 200
})
}
}

return (
<div className='page-login-animate flex justify-center items-center h-screen bg-gradient-to-r from-indigo-300 via-purple-300 to-pink-300'>
<div
ref={containerRef}
className='login-container-1 relative flex items-center justify-center shadow-2xl sm:w-3/4 xl:w-1/2 h-1/2 bg-white rounded-3xl'
>
{/* sign in box */}
<div className='box-sign box-sign-anime1 inset-0 absolute flex flex-col h-full w-1/2 p-10 justify-center items-center'>
<div className='text-3xl text-center font-bold'>Sign In</div>
<div className='flex justify-center items-center mt-5 mb-5 *:w-7 *:h-7 *:rounded-md *:mx-3 *:border *:flex *:justify-center *:items-center'>
<button className='hover:text-white hover:bg-gray-800 fa-brands fa-google-plus-g'></button>
<button className='hover:text-white hover:bg-gray-800 fa-brands fa-facebook-f'></button>
<button className='hover:text-white hover:bg-gray-800 fa-brands fa-github'></button>
<button className='hover:text-white hover:bg-gray-800 fa-brands fa-twitter'></button>
</div>
<div className='text-center text-gray-400'>
or use your email password
</div>
<input
className='bg-gray-200 rounded-md p-2 m-2 max-w-96 w-full'
type='text'
placeholder='Email'
/>
<input
className='bg-gray-200 rounded-md p-2 m-2 max-w-96 w-full'
type='password'
placeholder='Password'
/>
<div className='text-center text-gray-400 m-1'>
Forget Your Password?
</div>
<div className='flex justify-center w-1/2'>
<button className='bg-violet-700 hover:bg-violet-800 active:bg-violet-900 text-white py-3 w-full rounded-md m-2 px-8'>
SIGN IN
</button>
</div>
</div>
{/* sign up box */}
<div className='box-sign box-sign-anime2 opacity-0 absolute inert-0 flex flex-col h-full w-1/2 p-10 justify-center items-center'>
<div className='text-3xl text-center font-bold'>Create Account</div>
<div className='flex justify-center items-center mt-5 mb-5 *:w-7 *:h-7 *:rounded-md *:mx-3 *:border *:flex *:justify-center *:items-center'>
<button className='hover:text-white hover:bg-gray-800 fa-brands fa-google-plus-g'></button>
<button className='hover:text-white hover:bg-gray-800 fa-brands fa-facebook-f'></button>
<button className='hover:text-white hover:bg-gray-800 fa-brands fa-github'></button>
<button className='hover:text-white hover:bg-gray-800 fa-brands fa-twitter'></button>
</div>
<div className='text-center text-gray-400'>
or use your email password
</div>
<input
className='bg-gray-200 rounded-md p-2 m-2 w-full md:max-w-64 xl:max-w-96'
type='text'
placeholder='Name'
/>
<input
className='bg-gray-200 rounded-md p-2 m-2 xl:max-w-96 w-full md:max-w-64'
type='text'
placeholder='Email'
/>
<input
className='bg-gray-200 rounded-md p-2 m-2 xl:max-w-96 w-full md:max-w-64'
type='password'
placeholder='Password'
/>
<div className='flex justify-center w-1/2 md:w-3/4'>
<button className='bg-violet-700 hover:bg-violet-800 active:bg-violet-900 text-white py-3 w-full rounded-md m-2 px-8 xl:max-w-64 md:max-w-64'>
SIGN UP
</button>
</div>
</div>
{/* sign up box desc */}
<div className='box-desc box-desc-anime1 absolute top-0 right-0 bg-violet-600 h-full flex flex-col justify-center items-center w-1/2 p-10 rounded-l-[25%]'>
{/* box-desc-son1 */}
<div className='flex absolute inset-0 box-desc-son1 justify-center flex-col items-center'>
<div className='text-white text-4xl font-bold my-3'>
Hello,Friend!
</div>
<p className='text-white my-5 text-center px-4'>
Register with your personal details to use all of site features
</p>
<div className='flex justify-center w-1/3'>
<button
onClick={() => animation(1)}
className='text-white border border-white py-3 w-full rounded-md m-2 hover:bg-violet-500 active:bg-violet-400'
>
SIGN UP
</button>
</div>
</div>
{/* box-desc-son2 */}
<div className='flex opacity-0 absolute inset-0 box-desc-son2 justify-center flex-col items-center'>
<div className='text-white text-4xl font-bold my-3'>
Welcome Back!
</div>
<p className='text-white my-5 text-center px-4'>
Enter your personal details to use all of site features
</p>
<div className='flex justify-center w-1/3'>
<button
onClick={() => animation(2)}
className='text-white border border-white py-3 w-full rounded-md m-2 hover:bg-violet-500 active:bg-violet-400'
>
SIGN IN
</button>
</div>
</div>
</div>
</div>
</div>
)
}

export default LoginAnimate

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.page-login-animate {
.login-container-1 {
.box-sign-anime1 {
z-index: 2;
}
.box-sign-anime2 {
z-index: 1;
}
.box-desc-son1 {
z-index: 2;
}
.box-desc-son2 {
z-index: 1;
}
}
}

参考资料

ASMR Programming - Animated Login Page - No Talking

Author: XavierShi
Link: https://blog.xaviershi.com/2024/07/12/炫酷的登录动画-001/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.