├── README.md ├── doc ├── html-struct.png └── preview.jpg ├── img ├── log.svg └── register.svg ├── index.html ├── main.js ├── style.css └── transition.html /README.md: -------------------------------------------------------------------------------- 1 | ![预览](./doc/preview.jpg) 2 | 3 | ## HTML 结构 4 | ![html结构](./doc/html-struct.png) 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 | maker launch -------------------------------------------------------------------------------- /img/register.svg: -------------------------------------------------------------------------------- 1 | press play -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | 11 | 12 | Landing... 13 | 14 | 21 | 22 | 23 |
24 |
25 | 31 | 37 |
38 |
39 | 45 | 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 | --------------------------------------------------------------------------------