├── README.md
├── doc
├── html-struct.png
└── preview.jpg
├── img
├── log.svg
└── register.svg
├── index.html
├── main.js
├── style.css
└── transition.html
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | ## HTML 结构
4 | 
5 |
6 | ## JS
7 | 为引导按钮注册click事件
8 | 给容器增删样式
9 |
10 | ## CSS
11 | 外层容器:
12 | 作为定位基准
13 |
14 | #### 背景:
15 | 通过伪元素实现并将背景设置成线性渐变,大小超过窗口。这样在x周平移是会形成滚动视觉效果,并将z-index设置为顶层,便于在动画过程中隐藏其他元素。
16 | #### 表单容器:
17 | z-index低于背景,快递大小要能让出背景留白的空间显示。布局方式使用grid,因为有登录注册两个表单,相对于重复定位grid更为简便。
18 |
19 | #### 引导容器:
20 | z-index不用设置。子元素设置为背景统计,并通过pointer-event属性实现事件穿透操作表单。
21 |
22 | ## 动画
23 | 背景:X:0 –> 100%;动画延迟0,动画时间1.8s
24 | 表单容器:left:75% -> 25%;动画延迟1s,动画时间0.7s
25 | 登录表单:z-index:4 -> 3
26 | 注册表单:z-index:3 -> 4
27 | 注册引导:X:800px –> 0
28 | 登录引导:X:0 -> -800px
29 | 引导内容:动画延迟0.6s,动画时间0.9s
30 | 引导图片:动画延迟0.5s,动画时间0.9s
31 |
32 | ## 响应式
33 | 逻辑与上述相似,不再赘述
34 |
35 | ## 有趣的知识点:
36 | z-index:https://developer.mozilla.org/zh-CN/docs/Web/CSS/z-index
37 | pointer-event:https://developer.mozilla.org/zh-CN/docs/Web/API/Pointer_events
38 | display:grid:
39 | https://developer.mozilla.org/zh-CN/docs/Web/CSS/grid |
40 | https://drafts.csswg.org/css-grid/#propdef-grid
41 | transition-timing-function:https://developer.mozilla.org/zh-CN/docs/Web/CSS/transition-timing-function(可查看transition.html对比效果)
--------------------------------------------------------------------------------
/doc/html-struct.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zeroojs/landing-ux/cbf6461ef05f9d1c00b70e190fdcc4bd858a7a48/doc/html-struct.png
--------------------------------------------------------------------------------
/doc/preview.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zeroojs/landing-ux/cbf6461ef05f9d1c00b70e190fdcc4bd858a7a48/doc/preview.jpg
--------------------------------------------------------------------------------
/img/log.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/img/register.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
10 |
11 |
12 | Landing...
13 |
14 |
21 |
22 |
23 |
24 |
38 |
39 |
40 |
41 |
42 |
43 |

44 |
45 |
46 |
47 |
48 |
49 |

50 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/main.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Author: Minyoung
3 | * CreateAt: 2021年10月14日23:44:45
4 | * License: MIT
5 | */
6 | const singUpBtn = document.querySelector('#sign-up-btn')
7 | const singInBtn = document.querySelector('#sign-in-btn')
8 | const container = document.querySelector('.container')
9 |
10 | singUpBtn.addEventListener('click', () => {
11 | container.classList.add('sign-up-mode')
12 | })
13 | singInBtn.addEventListener('click', () => {
14 | container.classList.remove('sign-up-mode')
15 | })
16 |
17 |
18 |
--------------------------------------------------------------------------------
/style.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Author: Minyoung
3 | * CreateAt: 2021年10月14日23:44:45
4 | * License: MIT
5 | */
6 | * {
7 | padding: 0;
8 | margin: 0;
9 | box-sizing: border-box;
10 | color: #333;
11 | }
12 |
13 | .container {
14 | position: relative;
15 | min-height: 100vh;
16 | width: 100%;
17 | overflow: hidden;
18 | }
19 | .container::before {
20 | content: " ";
21 | position: absolute;
22 | width: 2000px;
23 | height: 2000px;
24 | border-radius: 50%;
25 | background-image: linear-gradient(-45deg, #6266f5 0%, #04befe 100%);
26 | transition: 1.8s ease-in-out;
27 | z-index: 6;
28 | top: -10%;
29 | right: 48%;
30 | transform: translateY(-50%);
31 | }
32 | .container.sign-up-mode::before {
33 | transform: translate(100%, -50%);
34 | }
35 |
36 | .form-warp {
37 | width: 50%;
38 | position: absolute;
39 | z-index: 5;
40 | left: 75%;
41 | top: 50%;
42 | z-index: 5;
43 | transform: translate(-50%, -50%);
44 | display: grid;
45 | grid-template-columns: 1fr;
46 | transition: 1s 0.7s ease-in-out;
47 | }
48 | .form-warp form {
49 | display: flex;
50 | align-items: center;
51 | justify-content: center;
52 | flex-direction: column;
53 | gap: 20px;
54 | /* 将两个 form 布局在 grid 同一位置 */
55 | grid-row: 1 / 2;
56 | grid-column: 1 / 2;
57 | transition: all 0.2s 0.7s;
58 | opacity: 1;
59 | z-index: 4;
60 | }
61 | .form-title {
62 | color: #6266f5;
63 | }
64 | .form-warp .sign-up-form {
65 | opacity: 0;
66 | z-index: 3;
67 | }
68 | .container.sign-up-mode .form-warp {
69 | left: 25%;
70 | }
71 | .container.sign-up-mode .sign-in-form {
72 | opacity: 0;
73 | z-index: 3;
74 | }
75 | .container.sign-up-mode .sign-up-form {
76 | opacity: 1;
77 | z-index: 4;
78 | }
79 | input,
80 | .submit-btn {
81 | min-width: 300px;
82 | outline: none;
83 | padding: 12px 30px;
84 | line-height: 1;
85 | font-size: 16px;
86 | border-radius: 60px;
87 | color: #333;
88 | background-color: #6267f513;
89 | border: none;
90 | }
91 | input::placeholder {
92 | color: #cccc;
93 | }
94 | .submit-btn {
95 | background-color: #6266f5;
96 | color: #FFF;
97 | text-align: center;
98 | min-width: 150px;
99 | font-size: initial;
100 | font-weight: bold;
101 | letter-spacing: 1.5px;
102 | cursor: pointer;
103 | }
104 |
105 | .desc-warp {
106 | width: 100%;
107 | height: 100%;
108 | position: absolute;
109 | top: 0;
110 | left: 0;
111 | display: grid;
112 | grid-template-columns: repeat(2, 1fr);
113 | }
114 | .desc-warp-item {
115 | display: flex;
116 | flex-direction: column;
117 | align-items: flex-end;
118 | justify-content: space-around;
119 | text-align: center;
120 | text-align: center;
121 | padding: 3rem 17% 2rem 12%;
122 | z-index: 6;
123 | }
124 | /* 事件穿透 BEGIN */
125 | .sign-in-desc {
126 | pointer-events: none;
127 | }
128 | .sign-up-mode .sign-in-desc {
129 | pointer-events: all;
130 | }
131 | .sign-up-mode .sign-up-desc {
132 | pointer-events: none;
133 | }
134 | /* 事件穿透 END */
135 | .content {
136 | width: 100%;
137 | transition: transform 0.9s ease-in-out;
138 | transition-delay: .6s;
139 | }
140 | .sign-in-desc img,
141 | .sign-in-desc .content {
142 | transform: translateX(800px);
143 | }
144 | .sign-up-mode .sign-in-desc img,
145 | .sign-up-mode .sign-in-desc .content {
146 | transform: translateX(0);
147 | }
148 |
149 | .sign-up-mode .sign-up-desc img,
150 | .sign-up-mode .sign-up-desc .content {
151 | transform: translateX(-800px);
152 | }
153 |
154 | button {
155 | outline: none;
156 | padding: 6px 8px;
157 | min-width: 100px;
158 | text-align: center;
159 | border-radius: 30px;
160 | border: 2px solid #FFF;
161 | background: none;
162 | color: #FFF;
163 | cursor: pointer;
164 | transition: all .3s ease;
165 | }
166 | button:active {
167 | background: rgba(255, 255, 255, .1);
168 | }
169 | img {
170 | width: 100%;
171 | display: block;
172 | transition: transform 0.9s ease-in-out;
173 | transition-delay: .5s;
174 | }
175 |
176 | /* 响应式 */
177 | @media screen and (max-width: 870px) {
178 | .container::before {
179 | width: 1500px;
180 | height: 1500px;
181 | transform: translateX(-50%);
182 | left: 30%;
183 | bottom: 68%;
184 | right: initial;
185 | top: initial;
186 | transition: 2s ease-in-out;
187 | }
188 | .container.sign-up-mode::before {
189 | transform: translate(-50%, 100%);
190 | bottom: 32%;
191 | right: initial;
192 | }
193 | .form-warp {
194 | width: 100%;
195 | top: 75%;
196 | left: 50%;
197 | transform: translate(-50%, -100%);
198 | transition: 1s 0.8s ease-in-out;
199 | }
200 | .container.sign-up-mode .form-warp {
201 | top: 25%;
202 | left: 50%;
203 | transform: translate(-50%, 0);
204 | }
205 | img {
206 | width: 200px;
207 | transition: transform 0.9s ease-in-out;
208 | transition-delay: 0.7s;
209 | }
210 | .desc-warp {
211 | grid-template-columns: 1fr;
212 | grid-template-rows: 1fr 2fr 1fr;
213 | }
214 | .desc-warp-item {
215 | flex-direction: row;
216 | justify-content: space-around;
217 | align-items: center;
218 | padding: 2.5rem 8%;
219 | grid-column: 1 / 2;
220 | }
221 | .sign-in-desc {
222 | grid-row: 3 / 4;
223 | }
224 |
225 | .sign-in-desc img,
226 | .sign-in-desc .content {
227 | transform: translateY(800px);
228 | }
229 |
230 | .sign-up-mode .sign-in-desc img,
231 | .sign-up-mode .sign-in-desc .content {
232 | transform: translateY(0);
233 | }
234 |
235 | .sign-up-mode .sign-up-desc img,
236 | .sign-up-mode .sign-up-desc .content {
237 | transform: translateY(-800px);
238 | }
239 | }
240 |
241 | @media screen and (max-width: 570px) {
242 | .container::before {
243 | bottom: 72%;
244 | left: 50%;
245 | }
246 | img {
247 | display: none;
248 | }
249 | }
--------------------------------------------------------------------------------
/transition.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Transition
8 |
47 |
48 |
49 |
50 |
Action
51 |
ease
52 |
ease-in
53 |
ease-in
54 |
ease-in-out
55 |
69 |
70 |
71 |
--------------------------------------------------------------------------------