├── .gitignore ├── 1-searchBox ├── README.md ├── index.html └── search_style.css ├── 10-aliDriverLogin ├── JavaScript │ ├── login.css │ ├── login.html │ ├── logo.svg │ ├── qrcode.png │ └── script.js ├── Pure-CSS │ ├── login.css │ ├── login.html │ ├── logo.svg │ └── qrcode.png └── www.aliyundrive.com这是真正的阿里云盘的网址 ├── 11-glitchClock ├── dist │ ├── glitch.css │ ├── glitch位移距离更大更持久.css │ └── glitch闪烁更狂乱更电子感.css ├── glitch.scss └── index.html ├── 12-gradientText ├── index.html └── style.css ├── 13-PureCSSswiper ├── 1.jpg ├── 2.jpg ├── 3.jpg ├── 4.jpg ├── 5.jpg ├── index.html └── style.css ├── 2-cloverLoad ├── loading.css └── loading.html ├── 3-simpleLogin ├── login.css ├── login.html └── wallpaper.jpg ├── 4-turnOverLogin ├── login.css ├── login.html └── sakura.js ├── 5-GlassmorphismLogin ├── login.css ├── login.html ├── wallpaper.png └── wallpaper2.png ├── 6-CoverWithBand ├── band.css └── cover.html ├── 7-LovelyClock ├── clock.css ├── clock.html └── clock.js ├── 8-DigitalClock ├── clock.css ├── clock.html └── clock.js ├── 9-simpleShop ├── cover.png ├── icon.png ├── index.html └── style.css └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | 10-aliDriverLogin/logo.svg 3 | .vscode/ 4 | -------------------------------------------------------------------------------- /1-searchBox/README.md: -------------------------------------------------------------------------------- 1 | # Web 2 | 这个整个其实来自https://www.youtube.com/watch?v=v1PeTDrw6OY&t=41s 3 | 仅将fontawesome的放大镜更换为了svg 4 | -------------------------------------------------------------------------------- /1-searchBox/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 动态搜索框 6 | 7 | 8 | 9 | 10 | 16 | 17 | -------------------------------------------------------------------------------- /1-searchBox/search_style.css: -------------------------------------------------------------------------------- 1 | body{ 2 | margin: 0; 3 | padding: 0; 4 | /* background: #e94118; */ 5 | background-color: #FF670F; 6 | } 7 | 8 | .search-box{ 9 | position: absolute; 10 | top: 50%; 11 | left: 50%; 12 | transform: translate(-50%,-50%); 13 | background: #2f3640; 14 | height: 40px; 15 | border-radius: 40px; 16 | padding: 10px; 17 | display: flex; 18 | justify-content: center; 19 | } 20 | 21 | .search-box:hover>.search-txt{ 22 | width: 200px; 23 | padding: 0 6px; 24 | } 25 | 26 | .search-box:hover>.search-btn{ 27 | background: white; 28 | } 29 | 30 | .search-btn{ 31 | float: right; 32 | width: 40px; 33 | height: 40px; 34 | border-radius: 50%; 35 | background: #2f3640; 36 | display: flex; 37 | justify-content: center; 38 | align-items: center; 39 | transition: 0.4s; 40 | } 41 | 42 | .search-txt{ 43 | border: none; 44 | background: none; 45 | outline: none; 46 | float: left; 47 | padding: 0; 48 | color: white; 49 | font-size: 16px; 50 | transition: 0.4s; 51 | line-height: 40px; 52 | width: 0px; 53 | } -------------------------------------------------------------------------------- /10-aliDriverLogin/JavaScript/login.css: -------------------------------------------------------------------------------- 1 | body{ 2 | background-color: #ecefff; 3 | user-select: none; 4 | /* 这样用户点按钮的时候就不会选中文字, 更有沉浸感 */ 5 | /* 唉, 我没有教人做事的意思 */ 6 | 7 | display: flex; 8 | flex-direction: column; 9 | align-items: center; 10 | justify-content: center; 11 | height: 100vh; 12 | margin: 0; 13 | } 14 | 15 | .logo{ 16 | width: 216px; 17 | margin-bottom: 60px; 18 | } 19 | 20 | .login-app{ 21 | width: 348px; 22 | margin-bottom: 60px; 23 | } 24 | 25 | .login-header{ 26 | display: flex; 27 | } 28 | .login-header input[type="radio"]{ 29 | display: none; 30 | } 31 | .login-header label{ 32 | background-color: #f5f5f6; 33 | font-size: 18px; 34 | color: rgba(37, 38, 43, .36); 35 | 36 | padding: 16px; 37 | text-align: center; 38 | width: 100%; 39 | /* 这里并不是非得100%,利用的是flex的自动收缩,只要大于1/3就好了 */ 40 | 41 | cursor: pointer; 42 | } 43 | .login-header .m-btn{ 44 | border-top-left-radius: 12px; 45 | } 46 | .login-header .q-btn{ 47 | border-top-right-radius: 12px; 48 | } 49 | 50 | #message:checked + .m-btn, 51 | #username:checked + .u-btn, 52 | #qrcode:checked + .q-btn{ 53 | background-color: #fff; 54 | color: #25262b; 55 | cursor: default; 56 | } 57 | 58 | /* 接下来是个悲伤的故事, 我不想重演了 */ 59 | /* #message:checked~#form-bar{ 60 | left: 0; 61 | } 62 | 63 | #username:checked~#form-bar{ 64 | left: 348px; 65 | } 66 | 67 | #qrcode:checked~#form-bar{ 68 | left: 696px; 69 | } */ 70 | /* 又忘了只能影响同级之后的兄弟元素... */ 71 | /* 只能等CSS4了... */ 72 | 73 | .login-body{ 74 | overflow: hidden; 75 | border-radius: 0 0 20px 20px; 76 | background-color: #fff; 77 | 78 | -webkit-border-radius: 0 0 20px 20px; 79 | -moz-border-radius: 0 0 20px 20px; 80 | -ms-border-radius: 0 0 20px 20px; 81 | -o-border-radius: 0 0 20px 20px; 82 | } 83 | 84 | #form-bar{ 85 | display: flex; 86 | 87 | transition: transform .6s cubic-bezier(0.175, 0.885, 0.32, 1.275); 88 | /* 最初的打算其实本来是cubic-bezier(.25,.01,.25,1.3),但是觉得自己调的没有预设好最后就用了联想出来的 */ 89 | /* 这里其实是很重要的知识点:贝塞尔曲线. 但是我录视频的时候忘了讲!!! */ 90 | /* 因为实在是太困了来着,所以为什么录视频和做视频都拖到两天凌晨,太能拖了叭 */ 91 | /* 括号里的四个数字两两一组,分别是两个控制点的横坐标和纵坐标 */ 92 | /* 前面那个点和(时间轴和效果轴的起点(0,0))的连线是第一段曲度的控制线 */ 93 | /* 后面那个点是和(时间轴和效果轴的终点(1,1))连线是第二段曲度的控制线 */ 94 | /* 用过钢笔工具的话 就会有一个比较直观的理解 */ 95 | /* 推荐一个网站:https://cubic-bezier.com/ 可以直观地看到效果、拖曳式的调整、复制产生的结果 */ 96 | 97 | /* transform: translateX(-100px); */ 98 | 99 | -webkit-transition: transform .6s cubic-bezier(0.175, 0.885, 0.32, 1.275); 100 | -moz-transition: transform .6s cubic-bezier(0.175, 0.885, 0.32, 1.275); 101 | -ms-transition: transform .6s cubic-bezier(0.175, 0.885, 0.32, 1.275); 102 | -o-transition: transform .6s cubic-bezier(0.175, 0.885, 0.32, 1.275); 103 | } 104 | /* 这个时候我又有两个思路了 */ 105 | /* 首先想到的是,在两边各加一块白色的东西 */ 106 | /* form-append{ 107 | width: 100px; 108 | flex-shrink: 0; 109 | } */ 110 | /* 然后想到的是 */ 111 | /* 看上去好像第一种方法完全没必要 */ 112 | /* 但是这实际上是两种思路啊!!! */ 113 | 114 | .login-body form{ 115 | flex-shrink: 0; 116 | /* 使之不会被收缩,百度吧我讲不清我太菜了 */ 117 | width: 100%; 118 | 119 | box-sizing: border-box; 120 | padding: 22px; 121 | 122 | position: relative; 123 | } 124 | 125 | .login-body input{ 126 | outline: none; 127 | width: 100%; 128 | box-sizing: border-box; 129 | height: 46px; 130 | margin-bottom: 16px; 131 | background-color: rgba(39, 39, 41, .04); 132 | border: 1px solid transparent; 133 | border-radius: 8px; 134 | -webkit-border-radius: 8px; 135 | -moz-border-radius: 8px; 136 | -ms-border-radius: 8px; 137 | -o-border-radius: 8px; 138 | /* 这个插件有点烦的, 如果注释多的话 */ 139 | /* 这次代码也多, 演示的话我就先把它关了 */ 140 | /* 源代码里兼容性代码会有的 */ 141 | /* 好家伙我明明应该已经关了来着 */ 142 | /* 可能这就是老年痴呆吧 */ 143 | 144 | font-size: 14px; 145 | padding: 1px 12px; 146 | color: #25262b;/* 看不出来变化吧,哎嘿! */ 147 | } 148 | .login-body input::placeholder{ 149 | color: rgba(37, 38, 43, .36); 150 | } 151 | .login-body input:focus{ 152 | border: 1px solid rgba(99, 125, 255, .48); 153 | background-color: #fff; 154 | } 155 | 156 | .m-form .vercode-btn{ 157 | padding: 4px 12px; 158 | border-radius: 6px; 159 | font-size: 14px; 160 | color: #637dff; 161 | background-color: transparent; 162 | border: 1px solid rgba(99, 125, 255, .24); 163 | 164 | position: absolute; 165 | right: 36px; 166 | margin: 8px 0; 167 | 168 | -webkit-border-radius: 6px; 169 | -moz-border-radius: 6px; 170 | -ms-border-radius: 6px; 171 | -o-border-radius: 6px; 172 | } 173 | 174 | .login-body .login-btn{ 175 | width: 100%; 176 | height: 48px; 177 | border: none; 178 | border-radius: 10px; 179 | background: linear-gradient( 180 | 129.12deg,/* 沿着这个角度的线渐变 */ 181 | #446dff,/* 渐变起始颜色 */ 182 | rgba(99, 125 ,255, .75)/* 渐变终点颜色 */ 183 | );/* 为什么数值这么奇怪? -因为我直接copy官方的 */ 184 | 185 | color: #fff; 186 | font-size: 16px; 187 | 188 | margin-top: 16px; 189 | margin-bottom: 60px; 190 | } 191 | 192 | button{ 193 | cursor: pointer; 194 | } 195 | 196 | .m-form #sure{ 197 | display: none; 198 | } 199 | .m-form label.tobesure{ 200 | position: absolute; 201 | border: 2px solid rgba(132, 133, 141, .2); 202 | box-sizing: border-box; 203 | width: 16px; 204 | height: 16px; 205 | border-radius: 50%; 206 | cursor: pointer; 207 | 208 | left: 22px; 209 | } 210 | #sure:checked + label.tobesure{ 211 | background-color: #637dff; 212 | } 213 | /* 文字位置安排好了, 现在来整个小勾√ */ 214 | label.tobesure::after{ 215 | content: ''; 216 | border: 2px solid #fff; 217 | position: absolute; 218 | width: 6px; 219 | height: 3px; 220 | border-top: none; 221 | border-right: none; 222 | transform: translate(-50%, -50%) rotate(-45deg); 223 | /* 先平移再旋转好(方便的那个"好")定位... */ 224 | /* 这样就形成了一个勾勾 */ 225 | /* 然后定位至圆圈中间 */ 226 | top: 45%; 227 | left: 50%; 228 | /* 等于说重新声明了transform, 所以应该放在一起 */ 229 | 230 | -webkit-transform: translate(-50%,-50%) rotate(-45deg); 231 | -moz-transform: translate(-50%,-50%) rotate(-45deg); 232 | -ms-transform: translate(-50%,-50%) rotate(-45deg); 233 | -o-transform: translate(-50%,-50%) rotate(-45deg); 234 | -webkit-transform: translate(-50%,-50%) rotate(-45deg); 235 | } 236 | 237 | #sure:not(:checked) ~ .login-btn{ 238 | opacity: .5; 239 | cursor: not-allowed; 240 | /* 试了:disabled和unchecked和:not(:checked)都不行,就只好让按钮原本半透明,:checked以后不透明 */ 241 | /* 结果也没用 */ 242 | /* 哦是因为元素顺序, 又忘了, 真丢人 */ 243 | /* 这里懒得复现问题了! 所以是这么个呈现形式! 这是当时的注释! */ 244 | } 245 | 246 | label.tobesure{ 247 | bottom: 45px; 248 | } 249 | label.tobesure p{ 250 | margin: 0; 251 | margin-left: 20px; 252 | width: 280px; 253 | 254 | font-size: 12px; 255 | line-height: 1.5; 256 | color: rgba(37, 38, 43, .36); 257 | 258 | position: relative; 259 | bottom: 3px; 260 | /* relative是相对自己原本的位置移动 */ 261 | /* 这里也就是向上移动3px */ 262 | /* 其实只是为了一点强迫症 */ 263 | } 264 | label.tobesure p a{ 265 | text-decoration: none; 266 | color: #637dff; 267 | padding: 0 5px; 268 | } 269 | 270 | .qrcode{ 271 | width: 128px; 272 | height: 128px; 273 | box-shadow: 0px 0px 1px 1px rgba(28, 28, 32, 0.05), 0px 8px 24px rgba(28, 28, 32, 0.12); 274 | padding: 8px; 275 | box-sizing: border-box;/* 就应该写*里, 后悔了, 来不及了 */ 276 | border-radius: 10px; 277 | 278 | position: absolute; 279 | transform: translate(-50%, -50%); 280 | top: 40%; 281 | left: 50%; 282 | 283 | -webkit-border-radius: 10px; 284 | -moz-border-radius: 10px; 285 | -ms-border-radius: 10px; 286 | -o-border-radius: 10px; 287 | -webkit-transform: translate(-50%, -50%); 288 | -moz-transform: translate(-50%, -50%); 289 | -ms-transform: translate(-50%, -50%); 290 | -o-transform: translate(-50%, -50%); 291 | } 292 | .qrcode img{ 293 | width: 100%; 294 | } -------------------------------------------------------------------------------- /10-aliDriverLogin/JavaScript/login.html: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /10-aliDriverLogin/JavaScript/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /10-aliDriverLogin/JavaScript/qrcode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AuroraTea/Web/e8f6e747819114215d9f37273dd71bfd7875b535/10-aliDriverLogin/JavaScript/qrcode.png -------------------------------------------------------------------------------- /10-aliDriverLogin/JavaScript/script.js: -------------------------------------------------------------------------------- 1 | // 纯css计划告吹,老老实实js 2 | let login_opt = document.getElementsByName('login-opt'); 3 | let form_bar = document.getElementById('form-bar'); 4 | 5 | // 我最开始想到的思路是 6 | function checkRadio0(){ 7 | if(login_opt[0].checked){ 8 | form_bar.style.transform = 'translateX(0)'; 9 | console.log('1') 10 | } else if(login_opt[1].checked){ 11 | form_bar.style.transform = 'translateX(-348px)'; 12 | console.log('2') 13 | } else{ 14 | form_bar.style.transform = 'translateX(-692px)'; 15 | } 16 | } 17 | 18 | //而后我又有这么个思路 19 | function checkRadio(){ 20 | for(let i =0; i < login_opt.length; i++){ 21 | if(login_opt[i].checked){ 22 | form_bar.style.transform = 'translateX(' + (-348*i) + 'px)'; 23 | } 24 | } 25 | } 26 | //献丑了,大家喜欢哪种呢 -------------------------------------------------------------------------------- /10-aliDriverLogin/Pure-CSS/login.css: -------------------------------------------------------------------------------- 1 | body{ 2 | background-color: #ecefff; 3 | user-select: none; 4 | 5 | display: flex; 6 | flex-direction: column; 7 | align-items: center; 8 | justify-content: center; 9 | height: 100vh; 10 | margin: 0; 11 | } 12 | 13 | .logo{ 14 | width: 216px; 15 | margin-bottom: 60px; 16 | } 17 | 18 | .login-app{ 19 | width: 348px; 20 | margin-bottom: 60px; 21 | 22 | overflow: hidden; 23 | background-color: #fff; 24 | border-radius: 12px 12px 20px 20px; 25 | -webkit-border-radius: 12px 12px 20px 20px; 26 | -moz-border-radius: 12px 12px 20px 20px; 27 | -ms-border-radius: 12px 12px 20px 20px; 28 | -o-border-radius: 12px 12px 20px 20px; 29 | 30 | font-size: 0;/* 行内块在html里的回车造成页面里有空格 */ 31 | } 32 | 33 | 34 | input[type="radio"]{ 35 | display: none; 36 | } 37 | label.m-btn, 38 | label.u-btn, 39 | label.q-btn{ 40 | display: inline-block; 41 | background-color: #f5f5f6; 42 | font-size: 18px; 43 | color: rgba(37, 38, 43, .36); 44 | 45 | box-sizing: border-box; 46 | padding: 16px; 47 | text-align: center; 48 | /* width: 33.33%; */ 49 | /* 这个33.3%即使是33.33%都并不是三等分就很明显啊,我P1想吐槽的时候为什么在flex布局中就不明显呢 */ 50 | width: 116px; 51 | 52 | cursor: pointer; 53 | } 54 | .m-btn{ 55 | border-top-left-radius: 12px; 56 | } 57 | .q-btn{ 58 | border-top-right-radius: 12px; 59 | } 60 | 61 | #message:checked + .m-btn, 62 | #username:checked + .u-btn, 63 | #qrcode:checked + .q-btn{ 64 | background-color: #fff; 65 | color: #25262b; 66 | cursor: default; 67 | } 68 | 69 | /* 悲伤的故事不悲伤了! */ 70 | #message:checked ~ #form-bar{ 71 | transform: translateX(0); 72 | } 73 | 74 | #username:checked ~ #form-bar{ 75 | transform: translateX(-348px); 76 | } 77 | 78 | #qrcode:checked ~ #form-bar{ 79 | transform: translateX(-692px); 80 | } 81 | 82 | #form-bar{ 83 | display: flex; 84 | 85 | transition: transform .6s cubic-bezier(0.175, 0.885, 0.32, 1.275); 86 | 87 | -webkit-transition: transform .6s cubic-bezier(0.175, 0.885, 0.32, 1.275); 88 | -moz-transition: transform .6s cubic-bezier(0.175, 0.885, 0.32, 1.275); 89 | -ms-transition: transform .6s cubic-bezier(0.175, 0.885, 0.32, 1.275); 90 | -o-transition: transform .6s cubic-bezier(0.175, 0.885, 0.32, 1.275); 91 | } 92 | 93 | form{ 94 | flex-shrink: 0; 95 | width: 100%; 96 | 97 | box-sizing: border-box; 98 | padding: 22px; 99 | 100 | position: relative; 101 | } 102 | 103 | input{ 104 | outline: none; 105 | width: 100%; 106 | box-sizing: border-box; 107 | height: 46px; 108 | margin-bottom: 16px; 109 | background-color: rgba(39, 39, 41, .04); 110 | border: 1px solid transparent; 111 | border-radius: 8px; 112 | -webkit-border-radius: 8px; 113 | -moz-border-radius: 8px; 114 | -ms-border-radius: 8px; 115 | -o-border-radius: 8px; 116 | 117 | font-size: 14px; 118 | padding: 1px 12px; 119 | color: #25262b;/* 看不出来变化吧,哎嘿! */ 120 | } 121 | input::placeholder{ 122 | color: rgba(37, 38, 43, .36); 123 | } 124 | input:focus{ 125 | border: 1px solid rgba(99, 125, 255, .48); 126 | background-color: #fff; 127 | } 128 | 129 | .m-form .vercode-btn{ 130 | padding: 4px 12px; 131 | border-radius: 6px; 132 | font-size: 14px; 133 | color: #637dff; 134 | background-color: transparent; 135 | border: 1px solid rgba(99, 125, 255, .24); 136 | 137 | position: absolute; 138 | right: 36px; 139 | margin: 8px 0; 140 | 141 | -webkit-border-radius: 6px; 142 | -moz-border-radius: 6px; 143 | -ms-border-radius: 6px; 144 | -o-border-radius: 6px; 145 | } 146 | 147 | .login-btn{ 148 | width: 100%; 149 | height: 48px; 150 | border: none; 151 | border-radius: 10px; 152 | background: linear-gradient( 153 | 129.12deg,/* 沿着这个角度的线渐变 */ 154 | #446dff,/* 渐变起始颜色 */ 155 | rgba(99, 125 ,255, .75)/* 渐变终点颜色 */ 156 | );/* 为什么数值这么奇怪? -因为我直接copy官方的 */ 157 | 158 | color: #fff; 159 | font-size: 16px; 160 | 161 | margin-top: 16px; 162 | margin-bottom: 60px; 163 | } 164 | 165 | button{ 166 | cursor: pointer; 167 | } 168 | 169 | .m-form #sure{ 170 | display: none; 171 | } 172 | .m-form label.tobesure{ 173 | position: absolute; 174 | border: 2px solid rgba(132, 133, 141, .2); 175 | box-sizing: border-box; 176 | width: 16px; 177 | height: 16px; 178 | border-radius: 50%; 179 | cursor: pointer; 180 | 181 | left: 22px; 182 | } 183 | #sure:checked + label.tobesure{ 184 | background-color: #637dff; 185 | } 186 | /* 文字位置安排好了, 现在来整个小勾√ */ 187 | label.tobesure::after{ 188 | content: ''; 189 | border: 2px solid #fff; 190 | position: absolute; 191 | width: 6px; 192 | height: 3px; 193 | border-top: none; 194 | border-right: none; 195 | transform: translate(-50%, -50%) rotate(-45deg); 196 | /* 先平移再旋转好(方便的那个"好")定位... */ 197 | /* 这样就形成了一个勾勾 */ 198 | /* 然后定位至圆圈中间 */ 199 | top: 45%; 200 | left: 50%; 201 | /* 等于说重新声明了transform, 所以应该放在一起 */ 202 | 203 | -webkit-transform: translate(-50%,-50%) rotate(-45deg); 204 | -moz-transform: translate(-50%,-50%) rotate(-45deg); 205 | -ms-transform: translate(-50%,-50%) rotate(-45deg); 206 | -o-transform: translate(-50%,-50%) rotate(-45deg); 207 | -webkit-transform: translate(-50%,-50%) rotate(-45deg); 208 | } 209 | 210 | #sure:not(:checked) ~ .login-btn{ 211 | opacity: .5; 212 | cursor: not-allowed; 213 | /* 试了:disabled和unchecked和:not(:checked)都不行,就只好让按钮原本半透明,:checked以后不透明 */ 214 | /* 结果也没用 */ 215 | /* 哦是因为元素顺序, 又忘了, 真丢人 */ 216 | /* 这里懒得复现问题了! 所以是这么个呈现形式! 这是当时的注释! */ 217 | } 218 | 219 | label.tobesure{ 220 | bottom: 45px; 221 | } 222 | label.tobesure p{ 223 | margin: 0; 224 | margin-left: 20px; 225 | width: 280px; 226 | 227 | font-size: 12px; 228 | line-height: 1.5; 229 | color: rgba(37, 38, 43, .36); 230 | 231 | position: relative; 232 | bottom: 3px; 233 | /* relative是相对自己原本的位置移动 */ 234 | /* 这里也就是向上移动3px */ 235 | /* 其实只是为了一点强迫症 */ 236 | } 237 | label.tobesure p a{ 238 | text-decoration: none; 239 | color: #637dff; 240 | padding: 0 5px; 241 | } 242 | 243 | .qrcode{ 244 | width: 128px; 245 | height: 128px; 246 | box-shadow: 0px 0px 1px 1px rgba(28, 28, 32, 0.05), 0px 8px 24px rgba(28, 28, 32, 0.12); 247 | padding: 8px; 248 | box-sizing: border-box;/* 就应该写*里, 后悔了, 来不及了 */ 249 | border-radius: 10px; 250 | 251 | position: absolute; 252 | transform: translate(-50%, -50%); 253 | top: 40%; 254 | left: 50%; 255 | 256 | -webkit-border-radius: 10px; 257 | -moz-border-radius: 10px; 258 | -ms-border-radius: 10px; 259 | -o-border-radius: 10px; 260 | -webkit-transform: translate(-50%, -50%); 261 | -moz-transform: translate(-50%, -50%); 262 | -ms-transform: translate(-50%, -50%); 263 | -o-transform: translate(-50%, -50%); 264 | } 265 | .qrcode img{ 266 | width: 100%; 267 | } -------------------------------------------------------------------------------- /10-aliDriverLogin/Pure-CSS/login.html: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /10-aliDriverLogin/Pure-CSS/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /10-aliDriverLogin/Pure-CSS/qrcode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AuroraTea/Web/e8f6e747819114215d9f37273dd71bfd7875b535/10-aliDriverLogin/Pure-CSS/qrcode.png -------------------------------------------------------------------------------- /10-aliDriverLogin/www.aliyundrive.com这是真正的阿里云盘的网址: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AuroraTea/Web/e8f6e747819114215d9f37273dd71bfd7875b535/10-aliDriverLogin/www.aliyundrive.com这是真正的阿里云盘的网址 -------------------------------------------------------------------------------- /11-glitchClock/dist/glitch.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.font.im/css?family=Black+Ops+One"); 2 | body { 3 | background-color: #000; 4 | display: flex; 5 | justify-content: center; 6 | align-items: center; 7 | height: 100vh; 8 | margin: 0; 9 | } 10 | 11 | #clock p { 12 | color: #fff; 13 | font-family: "Black Ops One"; 14 | font-size: 45px; 15 | letter-spacing: 2px; 16 | transform: scale(1.2); 17 | } 18 | 19 | #clock p:before, 20 | #clock p:after { 21 | content: attr(data-text); 22 | position: absolute; 23 | top: 0; 24 | left: 0; 25 | } 26 | 27 | #clock p:before { 28 | left: 2px; 29 | text-shadow: -2px 0 0 #27C0C8; 30 | animation: glitch-1 2s linear infinite reverse; 31 | } 32 | 33 | #clock p:after { 34 | left: -2px; 35 | text-shadow: -2px 0 0 #EA41B6; 36 | animation: glitch-2 2s linear infinite reverse; 37 | } 38 | 39 | @keyframes glitch-1 { 40 | 0% { 41 | clip: rect(98px, 350px, 10px, 0px); 42 | } 43 | 5% { 44 | clip: rect(60px, 350px, 25px, 0px); 45 | } 46 | 10% { 47 | clip: rect(65px, 350px, 44px, 0px); 48 | } 49 | 15% { 50 | clip: rect(71px, 350px, 31px, 0px); 51 | } 52 | 20% { 53 | clip: rect(72px, 350px, 76px, 0px); 54 | } 55 | 25% { 56 | clip: rect(60px, 350px, 84px, 0px); 57 | } 58 | 30% { 59 | clip: rect(96px, 350px, 94px, 0px); 60 | } 61 | 35% { 62 | clip: rect(14px, 350px, 55px, 0px); 63 | } 64 | 40% { 65 | clip: rect(97px, 350px, 59px, 0px); 66 | } 67 | 45% { 68 | clip: rect(15px, 350px, 7px, 0px); 69 | } 70 | 50% { 71 | clip: rect(91px, 350px, 97px, 0px); 72 | } 73 | 55% { 74 | clip: rect(1px, 350px, 77px, 0px); 75 | } 76 | 60% { 77 | clip: rect(31px, 350px, 27px, 0px); 78 | } 79 | 65% { 80 | clip: rect(82px, 350px, 88px, 0px); 81 | } 82 | 70% { 83 | clip: rect(10px, 350px, 90px, 0px); 84 | } 85 | 75% { 86 | clip: rect(95px, 350px, 20px, 0px); 87 | } 88 | 80% { 89 | clip: rect(24px, 350px, 93px, 0px); 90 | } 91 | 85% { 92 | clip: rect(58px, 350px, 81px, 0px); 93 | } 94 | 90% { 95 | clip: rect(28px, 350px, 34px, 0px); 96 | } 97 | 95% { 98 | clip: rect(55px, 350px, 98px, 0px); 99 | } 100 | 100% { 101 | clip: rect(91px, 350px, 29px, 0px); 102 | } 103 | } 104 | @keyframes glitch-2 { 105 | 0% { 106 | clip: rect(73px, 350px, 95px, 0px); 107 | } 108 | 5% { 109 | clip: rect(52px, 350px, 73px, 0px); 110 | } 111 | 10% { 112 | clip: rect(42px, 350px, 24px, 0px); 113 | } 114 | 15% { 115 | clip: rect(79px, 350px, 91px, 0px); 116 | } 117 | 20% { 118 | clip: rect(92px, 350px, 13px, 0px); 119 | } 120 | 25% { 121 | clip: rect(64px, 350px, 87px, 0px); 122 | } 123 | 30% { 124 | clip: rect(12px, 350px, 78px, 0px); 125 | } 126 | 35% { 127 | clip: rect(11px, 350px, 22px, 0px); 128 | } 129 | 40% { 130 | clip: rect(6px, 350px, 59px, 0px); 131 | } 132 | 45% { 133 | clip: rect(45px, 350px, 81px, 0px); 134 | } 135 | 50% { 136 | clip: rect(1px, 350px, 79px, 0px); 137 | } 138 | 55% { 139 | clip: rect(96px, 350px, 11px, 0px); 140 | } 141 | 60% { 142 | clip: rect(87px, 350px, 55px, 0px); 143 | } 144 | 65% { 145 | clip: rect(58px, 350px, 80px, 0px); 146 | } 147 | 70% { 148 | clip: rect(7px, 350px, 57px, 0px); 149 | } 150 | 75% { 151 | clip: rect(52px, 350px, 53px, 0px); 152 | } 153 | 80% { 154 | clip: rect(63px, 350px, 64px, 0px); 155 | } 156 | 85% { 157 | clip: rect(71px, 350px, 99px, 0px); 158 | } 159 | 90% { 160 | clip: rect(98px, 350px, 72px, 0px); 161 | } 162 | 95% { 163 | clip: rect(63px, 350px, 98px, 0px); 164 | } 165 | 100% { 166 | clip: rect(32px, 350px, 57px, 0px); 167 | } 168 | } -------------------------------------------------------------------------------- /11-glitchClock/dist/glitch位移距离更大更持久.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.font.im/css?family=Black+Ops+One"); 2 | body { 3 | background-color: #000; 4 | display: flex; 5 | justify-content: center; 6 | align-items: center; 7 | height: 100vh; 8 | margin: 0; 9 | } 10 | 11 | #clock p { 12 | color: #fff; 13 | font-family: "Black Ops One"; 14 | font-size: 45px; 15 | letter-spacing: 2px; 16 | transform: scale(1.2); 17 | } 18 | 19 | #clock p:before, 20 | #clock p:after { 21 | content: attr(data-text); 22 | position: absolute; 23 | top: 0; 24 | left: 0; 25 | } 26 | 27 | #clock p:before { 28 | left: 2px; 29 | text-shadow: -2px 0 0 #27C0C8; 30 | animation: glitch-1 2s linear infinite reverse; 31 | } 32 | 33 | #clock p:after { 34 | left: -2px; 35 | text-shadow: -2px 0 0 #EA41B6; 36 | animation: glitch-2 2s linear infinite reverse; 37 | } 38 | 39 | @keyframes glitch-1 { 40 | 0% { 41 | clip: rect(33px, 350px, 50px, 0px); 42 | } 43 | 5% { 44 | clip: rect(93px, 350px, 98px, 0px); 45 | } 46 | 10% { 47 | clip: rect(26px, 350px, 18px, 0px); 48 | } 49 | 15% { 50 | clip: rect(86px, 350px, 94px, 0px); 51 | } 52 | 20% { 53 | clip: rect(17px, 350px, 10px, 0px); 54 | } 55 | 25% { 56 | clip: rect(78px, 350px, 84px, 0px); 57 | } 58 | 30% { 59 | clip: rect(87px, 350px, 83px, 0px); 60 | } 61 | 35% { 62 | clip: rect(99px, 350px, 35px, 0px); 63 | } 64 | 40% { 65 | clip: rect(26px, 350px, 63px, 0px); 66 | } 67 | 45% { 68 | clip: rect(20px, 350px, 65px, 0px); 69 | } 70 | 50% { 71 | clip: rect(25px, 350px, 37px, 0px); 72 | } 73 | 55% { 74 | clip: rect(45px, 350px, 91px, 0px); 75 | } 76 | 60% { 77 | clip: rect(53px, 350px, 75px, 0px); 78 | } 79 | 65% { 80 | clip: rect(23px, 350px, 26px, 0px); 81 | } 82 | 70% { 83 | clip: rect(59px, 350px, 86px, 0px); 84 | } 85 | 75% { 86 | clip: rect(1px, 350px, 8px, 0px); 87 | } 88 | 80% { 89 | clip: rect(24px, 350px, 25px, 0px); 90 | } 91 | 85% { 92 | clip: rect(100px, 350px, 97px, 0px); 93 | } 94 | 90% { 95 | clip: rect(83px, 350px, 34px, 0px); 96 | } 97 | 95% { 98 | clip: rect(43px, 350px, 53px, 0px); 99 | } 100 | 100% { 101 | clip: rect(67px, 350px, 35px, 0px); 102 | } 103 | } 104 | @keyframes glitch-2 { 105 | 0% { 106 | clip: rect(11px, 350px, 58px, 0px); 107 | } 108 | 5% { 109 | clip: rect(48px, 350px, 94px, 0px); 110 | } 111 | 10% { 112 | clip: rect(62px, 350px, 61px, 0px); 113 | } 114 | 15% { 115 | clip: rect(63px, 350px, 44px, 0px); 116 | } 117 | 20% { 118 | clip: rect(36px, 350px, 29px, 0px); 119 | } 120 | 25% { 121 | clip: rect(44px, 350px, 53px, 0px); 122 | } 123 | 30% { 124 | clip: rect(92px, 350px, 95px, 0px); 125 | } 126 | 35% { 127 | clip: rect(79px, 350px, 59px, 0px); 128 | } 129 | 40% { 130 | clip: rect(82px, 350px, 35px, 0px); 131 | } 132 | 45% { 133 | clip: rect(50px, 350px, 46px, 0px); 134 | } 135 | 50% { 136 | clip: rect(97px, 350px, 23px, 0px); 137 | } 138 | 55% { 139 | clip: rect(98px, 350px, 52px, 0px); 140 | } 141 | 60% { 142 | clip: rect(9px, 350px, 89px, 0px); 143 | } 144 | 65% { 145 | clip: rect(77px, 350px, 15px, 0px); 146 | } 147 | 70% { 148 | clip: rect(2px, 350px, 54px, 0px); 149 | } 150 | 75% { 151 | clip: rect(6px, 350px, 9px, 0px); 152 | } 153 | 80% { 154 | clip: rect(19px, 350px, 52px, 0px); 155 | } 156 | 85% { 157 | clip: rect(82px, 350px, 69px, 0px); 158 | } 159 | 90% { 160 | clip: rect(38px, 350px, 100px, 0px); 161 | } 162 | 95% { 163 | clip: rect(60px, 350px, 26px, 0px); 164 | } 165 | 100% { 166 | clip: rect(62px, 350px, 59px, 0px); 167 | } 168 | } -------------------------------------------------------------------------------- /11-glitchClock/dist/glitch闪烁更狂乱更电子感.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.font.im/css?family=Black+Ops+One"); 2 | * { 3 | margin: 0; 4 | padding: 0; 5 | } 6 | 7 | body { 8 | height: 100vh; 9 | overflow: hidden; 10 | background-color: #000; 11 | display: flex; 12 | justify-content: center; 13 | align-items: center; 14 | overflow: hidden; 15 | } 16 | 17 | #clock p { 18 | color: #fff; 19 | font-size: 45px; 20 | letter-spacing: 2px; 21 | font-family: "Black Ops One", sans-serif; 22 | transform: scale(1.2); 23 | } 24 | 25 | #clock p:before, 26 | #clock p:after { 27 | content: attr(data-text); 28 | background-color: #000; 29 | color: #fff; 30 | position: absolute; 31 | top: 0; 32 | overflow: hidden; 33 | } 34 | 35 | #clock p:before { 36 | left: 2px; 37 | text-shadow: -2px 0 #27C0C8; 38 | animation: glitch-1 2s 0s linear reverse infinite; 39 | } 40 | 41 | #clock p:after { 42 | left: -2px; 43 | text-shadow: -2px 0 #EA41B6; 44 | animation: glitch-2 2s 0s linear reverse infinite; 45 | } 46 | 47 | @keyframes glitch-1 { 48 | 0% { 49 | clip: rect(53px, 350px, 67px, 0px); 50 | } 51 | 5% { 52 | clip: rect(100px, 350px, 82px, 0px); 53 | } 54 | 10% { 55 | clip: rect(56px, 350px, 80px, 0px); 56 | } 57 | 15% { 58 | clip: rect(64px, 350px, 42px, 0px); 59 | } 60 | 20% { 61 | clip: rect(49px, 350px, 61px, 0px); 62 | } 63 | 25% { 64 | clip: rect(69px, 350px, 28px, 0px); 65 | } 66 | 30% { 67 | clip: rect(35px, 350px, 19px, 0px); 68 | } 69 | 35% { 70 | clip: rect(83px, 350px, 31px, 0px); 71 | } 72 | 40% { 73 | clip: rect(14px, 350px, 1px, 0px); 74 | } 75 | 45% { 76 | clip: rect(60px, 350px, 87px, 0px); 77 | } 78 | 50% { 79 | clip: rect(81px, 350px, 26px, 0px); 80 | } 81 | 55% { 82 | clip: rect(67px, 350px, 60px, 0px); 83 | } 84 | 60% { 85 | clip: rect(74px, 350px, 57px, 0px); 86 | } 87 | 65% { 88 | clip: rect(10px, 350px, 56px, 0px); 89 | } 90 | 70% { 91 | clip: rect(92px, 350px, 22px, 0px); 92 | } 93 | 75% { 94 | clip: rect(88px, 350px, 78px, 0px); 95 | } 96 | 80% { 97 | clip: rect(67px, 350px, 22px, 0px); 98 | } 99 | 85% { 100 | clip: rect(19px, 350px, 67px, 0px); 101 | } 102 | 90% { 103 | clip: rect(70px, 350px, 58px, 0px); 104 | } 105 | 95% { 106 | clip: rect(65px, 350px, 71px, 0px); 107 | } 108 | 100% { 109 | clip: rect(77px, 350px, 85px, 0px); 110 | } 111 | } 112 | @keyframes glitch-2 { 113 | 0% { 114 | clip: rect(99px, 350px, 45px, 0px); 115 | } 116 | 5% { 117 | clip: rect(93px, 350px, 77px, 0px); 118 | } 119 | 10% { 120 | clip: rect(88px, 350px, 12px, 0px); 121 | } 122 | 15% { 123 | clip: rect(32px, 350px, 77px, 0px); 124 | } 125 | 20% { 126 | clip: rect(73px, 350px, 27px, 0px); 127 | } 128 | 25% { 129 | clip: rect(92px, 350px, 1px, 0px); 130 | } 131 | 30% { 132 | clip: rect(80px, 350px, 83px, 0px); 133 | } 134 | 35% { 135 | clip: rect(42px, 350px, 14px, 0px); 136 | } 137 | 40% { 138 | clip: rect(6px, 350px, 13px, 0px); 139 | } 140 | 45% { 141 | clip: rect(40px, 350px, 1px, 0px); 142 | } 143 | 50% { 144 | clip: rect(43px, 350px, 99px, 0px); 145 | } 146 | 55% { 147 | clip: rect(88px, 350px, 59px, 0px); 148 | } 149 | 60% { 150 | clip: rect(90px, 350px, 36px, 0px); 151 | } 152 | 65% { 153 | clip: rect(6px, 350px, 2px, 0px); 154 | } 155 | 70% { 156 | clip: rect(36px, 350px, 49px, 0px); 157 | } 158 | 75% { 159 | clip: rect(93px, 350px, 70px, 0px); 160 | } 161 | 80% { 162 | clip: rect(36px, 350px, 40px, 0px); 163 | } 164 | 85% { 165 | clip: rect(27px, 350px, 22px, 0px); 166 | } 167 | 90% { 168 | clip: rect(96px, 350px, 80px, 0px); 169 | } 170 | 95% { 171 | clip: rect(67px, 350px, 69px, 0px); 172 | } 173 | 100% { 174 | clip: rect(82px, 350px, 17px, 0px); 175 | } 176 | } -------------------------------------------------------------------------------- /11-glitchClock/glitch.scss: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.font.im/css?family=Black+Ops+One'); 2 | 3 | body{ 4 | background-color: #000; 5 | 6 | display: flex; 7 | justify-content: center; 8 | align-items: center; 9 | height: 100vh; 10 | margin: 0; 11 | } 12 | 13 | #clock p{ 14 | color: #fff; 15 | font-family: 'Black Ops One'; 16 | font-size: 45px; 17 | letter-spacing: 2px; 18 | 19 | transform: scale(1.2); 20 | } 21 | 22 | #clock p:before, 23 | #clock p:after{ 24 | content: attr(data-text); 25 | 26 | position: absolute; 27 | top: 0; 28 | left: 0; 29 | } 30 | 31 | #clock p:before{ 32 | left: 2px; 33 | text-shadow: -2px 0 0 #27C0C8; 34 | animation: glitch-1 2s linear infinite reverse; 35 | } 36 | 37 | #clock p:after{ 38 | left: -2px; 39 | text-shadow: -2px 0 0 #EA41B6; 40 | animation: glitch-2 2s linear infinite reverse; 41 | } 42 | 43 | 44 | @keyframes glitch-1 { 45 | @for $i from 0 through 20 { 46 | #{percentage($i*(1/20))}{ 47 | clip: rect(random(100)+px, 350px, random(100)+px, 0px); 48 | } 49 | } 50 | } 51 | 52 | 53 | @keyframes glitch-2 { 54 | @for $i from 0 through 20 { 55 | #{percentage($i*(1/20))}{ 56 | clip: rect(random(100)+px, 350px, random(100)+px, 0px); 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /11-glitchClock/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 故障风时钟 8 | 9 | 10 | 11 |
12 |

{{time}}

13 |
14 | 15 | 16 | 36 | 37 | -------------------------------------------------------------------------------- /12-gradientText/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 渐变文字 8 | 9 | 10 | 11 |

我轻轻的招手,作别西天的云彩。

12 | 13 | -------------------------------------------------------------------------------- /12-gradientText/style.css: -------------------------------------------------------------------------------- 1 | *{ 2 | padding: 0; 3 | margin: 0; 4 | } 5 | 6 | body{ 7 | display: flex; 8 | justify-content: center; 9 | align-items: center; 10 | height: 100vh; 11 | } 12 | 13 | p{ 14 | font-size: 90px; 15 | font-weight: 700; 16 | font-family: '思源黑体 CN'; 17 | background-image: 18 | linear-gradient(90deg, 19 | #673ab7, 20 | #e91e63); 21 | background-clip: text; 22 | -webkit-background-clip: text; 23 | /* 这次的这句和以往不一样 */ 24 | /* 以往是考虑低版本浏览器 */ 25 | /* 这次就连最新版Chrome和Safari都需要 */ 26 | /* 注意是background-clip: text;需要 */ 27 | /* 如果是: content-box啊之类的就没这么苛刻的 */ 28 | /* -webkit-text-fill-color: transparent; */ 29 | color: transparent; 30 | /* 这个属性的-webkit-前缀也比较特殊 */ 31 | /* 寻常的-webkit-表示的是Chrome和Safari的私有属性 */ 32 | /* 但是它却声明了所有的(除了那位浏览器) */ 33 | background-image: 34 | linear-gradient(90deg, 35 | rgb(255, 167, 69), 36 | rgb(254, 134, 159), 37 | rgb(239, 122, 200), 38 | rgb(160, 131, 237), 39 | rgb(67, 174, 255), 40 | rgb(160, 131, 237), 41 | rgb(239, 122, 200), 42 | rgb(254, 134, 159), 43 | rgb(255, 167, 69)); 44 | background-size: 200%; 45 | } 46 | 47 | p{ 48 | -webkit-animation: streamer 2s linear infinite; 49 | animation: streamer 2s linear infinite; 50 | } 51 | 52 | @-webkit-keyframes streamer { 53 | 0%{ 54 | background-position: 0%; 55 | } 56 | 100%{ 57 | background-position: 200%; 58 | } 59 | } 60 | 61 | @keyframes streamer { 62 | 0%{ 63 | background-position: 0%; 64 | } 65 | 100%{ 66 | background-position: 200%; 67 | } 68 | } 69 | 70 | 71 | /* @media screen and (max-width: 1050px) { 72 | p{ 73 | font-size: 66px; 74 | } 75 | } 76 | @media screen and (max-width: 765px) { 77 | p{ 78 | font-size: 22px; 79 | } 80 | } */ -------------------------------------------------------------------------------- /13-PureCSSswiper/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AuroraTea/Web/e8f6e747819114215d9f37273dd71bfd7875b535/13-PureCSSswiper/1.jpg -------------------------------------------------------------------------------- /13-PureCSSswiper/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AuroraTea/Web/e8f6e747819114215d9f37273dd71bfd7875b535/13-PureCSSswiper/2.jpg -------------------------------------------------------------------------------- /13-PureCSSswiper/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AuroraTea/Web/e8f6e747819114215d9f37273dd71bfd7875b535/13-PureCSSswiper/3.jpg -------------------------------------------------------------------------------- /13-PureCSSswiper/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AuroraTea/Web/e8f6e747819114215d9f37273dd71bfd7875b535/13-PureCSSswiper/4.jpg -------------------------------------------------------------------------------- /13-PureCSSswiper/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AuroraTea/Web/e8f6e747819114215d9f37273dd71bfd7875b535/13-PureCSSswiper/5.jpg -------------------------------------------------------------------------------- /13-PureCSSswiper/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Pure CSS swiper 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /13-PureCSSswiper/style.css: -------------------------------------------------------------------------------- 1 | *{ 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | html{ 7 | font-size: 62.5%; 8 | } 9 | 10 | body{ 11 | display: flex; 12 | justify-content: center; 13 | align-items: center; 14 | height: 100vh; 15 | } 16 | 17 | .swiper{ 18 | display: flex; 19 | } 20 | 21 | img{ 22 | background-color: #666; 23 | 24 | height: 60rem; 25 | width: 10rem; 26 | margin: 1rem; 27 | 28 | border-radius: 20rem; 29 | 30 | object-fit: cover; 31 | } 32 | 33 | a:nth-child(1) img{ 34 | animation: swiper 30s infinite; 35 | } 36 | a:nth-child(2) img{ 37 | animation: swiper 30s 6s infinite; 38 | } 39 | a:nth-child(3) img{ 40 | animation: swiper 30s 12s infinite; 41 | } 42 | a:nth-child(4) img{ 43 | animation: swiper 30s 18s infinite; 44 | } 45 | a:nth-child(5) img{ 46 | animation: swiper 30s 24s infinite; 47 | } 48 | 49 | @keyframes swiper { 50 | 0%{ 51 | width: 10rem; 52 | border-radius: 20rem; 53 | } 54 | 1%{ 55 | width: 60rem; 56 | border-radius: 3.6rem; 57 | } 58 | 20%{ 59 | width: 60rem; 60 | border-radius: 3.6rem; 61 | } 62 | 21%{ 63 | width: 10rem; 64 | border-radius: 20rem; 65 | } 66 | 100%{ 67 | width: 10rem; 68 | border-radius: 20rem; 69 | } 70 | } 71 | 72 | /* @media (max-width: 1400px){ 73 | html{ 74 | font-size: 50%; 75 | } 76 | } 77 | 78 | @media (max-width: 500px){ 79 | html{ 80 | font-size: 20%; 81 | } 82 | } */ 83 | 84 | 85 | a:nth-child(1) img{ 86 | animation: swiper 15s infinite; 87 | } 88 | a:nth-child(2) img{ 89 | animation: swiper 15s 3s infinite; 90 | } 91 | a:nth-child(3) img{ 92 | animation: swiper 15s 6s infinite; 93 | } 94 | a:nth-child(4) img{ 95 | animation: swiper 15s 9s infinite; 96 | } 97 | a:nth-child(5) img{ 98 | animation: swiper 15s 12s infinite; 99 | } 100 | 101 | @keyframes swiper { 102 | 0%{ 103 | width: 10rem; 104 | border-radius: 20rem; 105 | } 106 | 2%{ 107 | width: 60rem; 108 | border-radius: 3.6rem; 109 | } 110 | 20%{ 111 | width: 60rem; 112 | border-radius: 3.6rem; 113 | } 114 | 22%{ 115 | width: 10rem; 116 | border-radius: 20rem; 117 | } 118 | 100%{ 119 | width: 10rem; 120 | border-radius: 20rem; 121 | } 122 | } -------------------------------------------------------------------------------- /2-cloverLoad/loading.css: -------------------------------------------------------------------------------- 1 | body{ 2 | margin: 0; 3 | padding: 0; 4 | height: 100vh; 5 | background-color: #1c1c1e; 6 | } 7 | 8 | .loading{ 9 | width: 76px; 10 | display: flex; 11 | flex-wrap: wrap; 12 | position: relative; 13 | top: 45%; 14 | margin: 0 auto; 15 | animation: rotate 3s linear infinite; 16 | } 17 | 18 | @keyframes rotate{ 19 | to{transform: rotate(360deg);} 20 | } 21 | 22 | .loading span{ 23 | width: 32px; 24 | height: 32px; 25 | margin: 3px; 26 | } 27 | 28 | .loading span:nth-child(1){ 29 | background-color: #e5efc1; 30 | border-radius: 50% 50% 0 50%; 31 | } 32 | .loading span:nth-child(2){ 33 | background-color: #a2d5ab; 34 | border-radius: 50% 50% 50% 0; 35 | } 36 | .loading span:nth-child(3){ 37 | background-color: #39aea9; 38 | border-radius: 50% 0 50% 50%; 39 | } 40 | .loading span:nth-child(4){ 41 | background-color: #557b83; 42 | border-radius: 0 50% 50% 50%; 43 | } -------------------------------------------------------------------------------- /2-cloverLoad/loading.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 水滴转转转loading 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | -------------------------------------------------------------------------------- /3-simpleLogin/login.css: -------------------------------------------------------------------------------- 1 | *{ 2 | user-select: none; 3 | /* 无法选中,整体感更强 */ 4 | } 5 | 6 | body{ 7 | background: url(./wallpaper.jpg) no-repeat; 8 | background-size: cover; 9 | background-attachment: fixed; 10 | } 11 | 12 | .login{ 13 | position: absolute; 14 | top: 50%; 15 | margin-top: -200px; 16 | left: 50%; 17 | margin-left: -200px; 18 | /* absolute居中的一种方法 */ 19 | background-color: whitesmoke; 20 | width: 400px; 21 | height: 400px; 22 | border-radius: 25px; 23 | text-align: center; 24 | padding: 5px 40px; 25 | box-sizing: border-box; 26 | /* 这样padding就不会影响大小 */ 27 | } 28 | 29 | p{ 30 | font-size: 42px; 31 | font-weight: 600; 32 | } 33 | 34 | input{ 35 | background-color: whitesmoke; 36 | width: 100%; 37 | height: 48px; 38 | margin-bottom: 10px; 39 | border: none; 40 | border-bottom: 2px solid silver; 41 | /* 下面的会覆盖上面的步伐 */ 42 | outline: none; 43 | font-size: 22px; 44 | } 45 | 46 | .btn{ 47 | background-color: #59c2c5; 48 | width: 38%; 49 | height: 48px; 50 | border-radius: 8px; 51 | margin-top: 40px; 52 | font-size: 28px; 53 | font-weight: 600; 54 | color: white; 55 | } 56 | .btn:hover{ 57 | background-color: #59c2a0; 58 | } -------------------------------------------------------------------------------- /3-simpleLogin/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Document 9 | 10 |
11 |

Login

12 | 13 | 14 | 15 |
16 | 17 | 18 | -------------------------------------------------------------------------------- /3-simpleLogin/wallpaper.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AuroraTea/Web/e8f6e747819114215d9f37273dd71bfd7875b535/3-simpleLogin/wallpaper.jpg -------------------------------------------------------------------------------- /4-turnOverLogin/login.css: -------------------------------------------------------------------------------- 1 | body{ 2 | background-color: #abdde8; 3 | 4 | overflow: hidden; 5 | margin: 0; 6 | height: 100vh; 7 | display: flex; 8 | justify-content: center; 9 | align-items: center; 10 | } 11 | 12 | .fixed{ 13 | position: fixed; 14 | top: 50%; 15 | left: 50%; 16 | transform: translate(-50%, -50%); 17 | } 18 | 19 | .form-demo{ 20 | position: relative; 21 | 22 | width: 400px; 23 | height: 600px; 24 | } 25 | 26 | /* 切换按钮所在的白色区域 */ 27 | .switch{ 28 | background-color: #FCFBFA; 29 | width: 100%; 30 | height: 140px; 31 | position: absolute; 32 | left: 0; 33 | bottom: 0; 34 | border-radius: 8px; 35 | text-align: center; 36 | } 37 | 38 | /* 切换按钮 */ 39 | #change:checked+label, 40 | /* +用来选择同级后面最近的元素 */ 41 | #change:not(:checked)+label{ 42 | background-color: #FFB8CE; 43 | color: white; 44 | width: 280px; 45 | padding: 8px 0; 46 | /* 用padding方便文字垂直居中 */ 47 | font-size: 24px; 48 | font-weight: 600; 49 | position: absolute; 50 | bottom: 22px; 51 | left: 50%; 52 | transform: translate(-50%); 53 | border-radius: 8px; 54 | cursor: pointer; 55 | text-align: center; 56 | } 57 | 58 | /* 旋转体 */ 59 | .turn{ 60 | width: 100%; 61 | height: 400px; 62 | position: absolute; 63 | top: 0; 64 | perspective: 800px; 65 | /* 旋转的时候的透视效果 */ 66 | } 67 | .over{ 68 | width: 100%; 69 | height: 100%; 70 | transform-style: preserve-3d; 71 | transition: all 1.6s ease; 72 | /* 旋转持续时间 */ 73 | /* ease是慢快慢 */ 74 | } 75 | #change:checked 76 | ~ 77 | .turn .over{ 78 | transform: rotateY(180deg); 79 | } 80 | form{ 81 | position: absolute; 82 | background-color: #FCFBFA; 83 | height: 100%; 84 | border-radius: 8px; 85 | transform-style: preserve-3d; 86 | text-align: center; 87 | } 88 | .sign{ 89 | transform: rotateY(180deg); 90 | } 91 | 92 | h1, h2{ 93 | color: #1f2029; 94 | user-select: none; 95 | } 96 | h1{ 97 | margin-top: 38px; 98 | transform-style: preserve-3d; 99 | transform: translate3d(0, 0, 1px); 100 | } 101 | 102 | input{ 103 | background-color: #4E495D; 104 | width: 70%; 105 | height: 48px; 106 | border-radius: 8px; 107 | margin-bottom: 20px; 108 | padding: 0 16px; 109 | font-size: 18px; 110 | color: #c4c3ca; 111 | font-weight: 500; 112 | outline: none; 113 | border: none; 114 | box-shadow: 0 4px 8px 0 rgba(78, 73, 79, .5); 115 | transform-style: preserve-3d; 116 | transform: translate3d(0, 0, 1px); 117 | } 118 | .login input:nth-child(-n+3){ 119 | /* 选择class为login的子元素中的前三个input */ 120 | margin: 20px 0; 121 | } 122 | 123 | .btn{ 124 | background-color: #981E61; 125 | border: none; 126 | width: 280px; 127 | font-size: 24px; 128 | font-weight: 600; 129 | padding: 6px 0; 130 | color: white; 131 | border-radius: 8px; 132 | margin-top: 15px; 133 | cursor: pointer; 134 | } -------------------------------------------------------------------------------- /4-turnOverLogin/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 樱花3D翻转 8 | 9 | 10 | 11 | 12 |
13 |
14 | 15 |

没有/已有账号?

16 | 17 | 18 | 19 |
20 |
21 | 27 |
28 |

加入我们

29 | 30 | 31 | 32 | 33 |
34 |
35 |
36 |
37 |
38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 137 | 209 | 210 | 223 | 243 | 259 | 280 | 281 | 296 | 297 | 308 | 330 | 331 | 332 | 333 | 334 | -------------------------------------------------------------------------------- /4-turnOverLogin/sakura.js: -------------------------------------------------------------------------------- 1 | // Utilities 2 | var Vector3 = {}; 3 | var Matrix44 = {}; 4 | Vector3.create = function(x, y, z) { 5 | return {'x':x, 'y':y, 'z':z}; 6 | }; 7 | Vector3.dot = function (v0, v1) { 8 | return v0.x * v1.x + v0.y * v1.y + v0.z * v1.z; 9 | }; 10 | Vector3.cross = function (v, v0, v1) { 11 | v.x = v0.y * v1.z - v0.z * v1.y; 12 | v.y = v0.z * v1.x - v0.x * v1.z; 13 | v.z = v0.x * v1.y - v0.y * v1.x; 14 | }; 15 | Vector3.normalize = function (v) { 16 | var l = v.x * v.x + v.y * v.y + v.z * v.z; 17 | if(l > 0.00001) { 18 | l = 1.0 / Math.sqrt(l); 19 | v.x *= l; 20 | v.y *= l; 21 | v.z *= l; 22 | } 23 | }; 24 | Vector3.arrayForm = function(v) { 25 | if(v.array) { 26 | v.array[0] = v.x; 27 | v.array[1] = v.y; 28 | v.array[2] = v.z; 29 | } 30 | else { 31 | v.array = new Float32Array([v.x, v.y, v.z]); 32 | } 33 | return v.array; 34 | }; 35 | Matrix44.createIdentity = function () { 36 | return new Float32Array([1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0]); 37 | }; 38 | Matrix44.loadProjection = function (m, aspect, vdeg, near, far) { 39 | var h = near * Math.tan(vdeg * Math.PI / 180.0 * 0.5) * 2.0; 40 | var w = h * aspect; 41 | 42 | m[0] = 2.0 * near / w; 43 | m[1] = 0.0; 44 | m[2] = 0.0; 45 | m[3] = 0.0; 46 | 47 | m[4] = 0.0; 48 | m[5] = 2.0 * near / h; 49 | m[6] = 0.0; 50 | m[7] = 0.0; 51 | 52 | m[8] = 0.0; 53 | m[9] = 0.0; 54 | m[10] = -(far + near) / (far - near); 55 | m[11] = -1.0; 56 | 57 | m[12] = 0.0; 58 | m[13] = 0.0; 59 | m[14] = -2.0 * far * near / (far - near); 60 | m[15] = 0.0; 61 | }; 62 | Matrix44.loadLookAt = function (m, vpos, vlook, vup) { 63 | var frontv = Vector3.create(vpos.x - vlook.x, vpos.y - vlook.y, vpos.z - vlook.z); 64 | Vector3.normalize(frontv); 65 | var sidev = Vector3.create(1.0, 0.0, 0.0); 66 | Vector3.cross(sidev, vup, frontv); 67 | Vector3.normalize(sidev); 68 | var topv = Vector3.create(1.0, 0.0, 0.0); 69 | Vector3.cross(topv, frontv, sidev); 70 | Vector3.normalize(topv); 71 | 72 | m[0] = sidev.x; 73 | m[1] = topv.x; 74 | m[2] = frontv.x; 75 | m[3] = 0.0; 76 | 77 | m[4] = sidev.y; 78 | m[5] = topv.y; 79 | m[6] = frontv.y; 80 | m[7] = 0.0; 81 | 82 | m[8] = sidev.z; 83 | m[9] = topv.z; 84 | m[10] = frontv.z; 85 | m[11] = 0.0; 86 | 87 | m[12] = -(vpos.x * m[0] + vpos.y * m[4] + vpos.z * m[8]); 88 | m[13] = -(vpos.x * m[1] + vpos.y * m[5] + vpos.z * m[9]); 89 | m[14] = -(vpos.x * m[2] + vpos.y * m[6] + vpos.z * m[10]); 90 | m[15] = 1.0; 91 | }; 92 | 93 | // 94 | var timeInfo = { 95 | 'start':0, 'prev':0, // Date 96 | 'delta':0, 'elapsed':0 // Number(sec) 97 | }; 98 | 99 | // 100 | var gl; 101 | var renderSpec = { 102 | 'width':0, 103 | 'height':0, 104 | 'aspect':1, 105 | 'array':new Float32Array(3), 106 | 'halfWidth':0, 107 | 'halfHeight':0, 108 | 'halfArray':new Float32Array(3) 109 | // and some render targets. see setViewport() 110 | }; 111 | renderSpec.setSize = function(w, h) { 112 | renderSpec.width = w; 113 | renderSpec.height = h; 114 | renderSpec.aspect = renderSpec.width / renderSpec.height; 115 | renderSpec.array[0] = renderSpec.width; 116 | renderSpec.array[1] = renderSpec.height; 117 | renderSpec.array[2] = renderSpec.aspect; 118 | 119 | renderSpec.halfWidth = Math.floor(w / 2); 120 | renderSpec.halfHeight = Math.floor(h / 2); 121 | renderSpec.halfArray[0] = renderSpec.halfWidth; 122 | renderSpec.halfArray[1] = renderSpec.halfHeight; 123 | renderSpec.halfArray[2] = renderSpec.halfWidth / renderSpec.halfHeight; 124 | }; 125 | 126 | function deleteRenderTarget(rt) { 127 | gl.deleteFramebuffer(rt.frameBuffer); 128 | gl.deleteRenderbuffer(rt.renderBuffer); 129 | gl.deleteTexture(rt.texture); 130 | } 131 | 132 | function createRenderTarget(w, h) { 133 | var ret = { 134 | 'width':w, 135 | 'height':h, 136 | 'sizeArray':new Float32Array([w, h, w / h]), 137 | 'dtxArray':new Float32Array([1.0 / w, 1.0 / h]) 138 | }; 139 | ret.frameBuffer = gl.createFramebuffer(); 140 | ret.renderBuffer = gl.createRenderbuffer(); 141 | ret.texture = gl.createTexture(); 142 | 143 | gl.bindTexture(gl.TEXTURE_2D, ret.texture); 144 | gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, w, h, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); 145 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); 146 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); 147 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); 148 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); 149 | 150 | gl.bindFramebuffer(gl.FRAMEBUFFER, ret.frameBuffer); 151 | gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, ret.texture, 0); 152 | 153 | gl.bindRenderbuffer(gl.RENDERBUFFER, ret.renderBuffer); 154 | gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, w, h); 155 | gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, ret.renderBuffer); 156 | 157 | gl.bindTexture(gl.TEXTURE_2D, null); 158 | gl.bindRenderbuffer(gl.RENDERBUFFER, null); 159 | gl.bindFramebuffer(gl.FRAMEBUFFER, null); 160 | 161 | return ret; 162 | } 163 | 164 | function compileShader(shtype, shsrc) { 165 | var retsh = gl.createShader(shtype); 166 | 167 | gl.shaderSource(retsh, shsrc); 168 | gl.compileShader(retsh); 169 | 170 | if(!gl.getShaderParameter(retsh, gl.COMPILE_STATUS)) { 171 | var errlog = gl.getShaderInfoLog(retsh); 172 | gl.deleteShader(retsh); 173 | console.error(errlog); 174 | return null; 175 | } 176 | return retsh; 177 | } 178 | 179 | function createShader(vtxsrc, frgsrc, uniformlist, attrlist) { 180 | var vsh = compileShader(gl.VERTEX_SHADER, vtxsrc); 181 | var fsh = compileShader(gl.FRAGMENT_SHADER, frgsrc); 182 | 183 | if(vsh == null || fsh == null) { 184 | return null; 185 | } 186 | 187 | var prog = gl.createProgram(); 188 | gl.attachShader(prog, vsh); 189 | gl.attachShader(prog, fsh); 190 | 191 | gl.deleteShader(vsh); 192 | gl.deleteShader(fsh); 193 | 194 | gl.linkProgram(prog); 195 | if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) { 196 | var errlog = gl.getProgramInfoLog(prog); 197 | console.error(errlog); 198 | return null; 199 | } 200 | 201 | if(uniformlist) { 202 | prog.uniforms = {}; 203 | for(var i = 0; i < uniformlist.length; i++) { 204 | prog.uniforms[uniformlist[i]] = gl.getUniformLocation(prog, uniformlist[i]); 205 | } 206 | } 207 | 208 | if(attrlist) { 209 | prog.attributes = {}; 210 | for(var i = 0; i < attrlist.length; i++) { 211 | var attr = attrlist[i]; 212 | prog.attributes[attr] = gl.getAttribLocation(prog, attr); 213 | } 214 | } 215 | 216 | return prog; 217 | } 218 | 219 | function useShader(prog) { 220 | gl.useProgram(prog); 221 | for(var attr in prog.attributes) { 222 | gl.enableVertexAttribArray(prog.attributes[attr]);; 223 | } 224 | } 225 | 226 | function unuseShader(prog) { 227 | for(var attr in prog.attributes) { 228 | gl.disableVertexAttribArray(prog.attributes[attr]);; 229 | } 230 | gl.useProgram(null); 231 | } 232 | 233 | ///// 234 | var projection = { 235 | 'angle':60, 236 | 'nearfar':new Float32Array([0.1, 100.0]), 237 | 'matrix':Matrix44.createIdentity() 238 | }; 239 | var camera = { 240 | 'position':Vector3.create(0, 0, 100), 241 | 'lookat':Vector3.create(0, 0, 0), 242 | 'up':Vector3.create(0, 1, 0), 243 | 'dof':Vector3.create(10.0, 4.0, 8.0), 244 | 'matrix':Matrix44.createIdentity() 245 | }; 246 | 247 | var pointFlower = {}; 248 | var meshFlower = {}; 249 | var sceneStandBy = false; 250 | 251 | var BlossomParticle = function () { 252 | this.velocity = new Array(3); 253 | this.rotation = new Array(3); 254 | this.position = new Array(3); 255 | this.euler = new Array(3); 256 | this.size = 1.0; 257 | this.alpha = 1.0; 258 | this.zkey = 0.0; 259 | }; 260 | 261 | BlossomParticle.prototype.setVelocity = function (vx, vy, vz) { 262 | this.velocity[0] = vx; 263 | this.velocity[1] = vy; 264 | this.velocity[2] = vz; 265 | }; 266 | 267 | BlossomParticle.prototype.setRotation = function (rx, ry, rz) { 268 | this.rotation[0] = rx; 269 | this.rotation[1] = ry; 270 | this.rotation[2] = rz; 271 | }; 272 | 273 | BlossomParticle.prototype.setPosition = function (nx, ny, nz) { 274 | this.position[0] = nx; 275 | this.position[1] = ny; 276 | this.position[2] = nz; 277 | }; 278 | 279 | BlossomParticle.prototype.setEulerAngles = function (rx, ry, rz) { 280 | this.euler[0] = rx; 281 | this.euler[1] = ry; 282 | this.euler[2] = rz; 283 | }; 284 | 285 | BlossomParticle.prototype.setSize = function (s) { 286 | this.size = s; 287 | }; 288 | 289 | BlossomParticle.prototype.update = function (dt, et) { 290 | this.position[0] += this.velocity[0] * dt; 291 | this.position[1] += this.velocity[1] * dt; 292 | this.position[2] += this.velocity[2] * dt; 293 | 294 | this.euler[0] += this.rotation[0] * dt; 295 | this.euler[1] += this.rotation[1] * dt; 296 | this.euler[2] += this.rotation[2] * dt; 297 | }; 298 | 299 | function createPointFlowers() { 300 | // get point sizes 301 | var prm = gl.getParameter(gl.ALIASED_POINT_SIZE_RANGE); 302 | renderSpec.pointSize = {'min':prm[0], 'max':prm[1]}; 303 | 304 | var vtxsrc = document.getElementById("sakura_point_vsh").textContent; 305 | var frgsrc = document.getElementById("sakura_point_fsh").textContent; 306 | 307 | pointFlower.program = createShader( 308 | vtxsrc, frgsrc, 309 | ['uProjection', 'uModelview', 'uResolution', 'uOffset', 'uDOF', 'uFade'], 310 | ['aPosition', 'aEuler', 'aMisc'] 311 | ); 312 | 313 | useShader(pointFlower.program); 314 | pointFlower.offset = new Float32Array([0.0, 0.0, 0.0]); 315 | pointFlower.fader = Vector3.create(0.0, 10.0, 0.0); 316 | 317 | // paramerters: velocity[3], rotate[3] 318 | pointFlower.numFlowers = 1600; 319 | pointFlower.particles = new Array(pointFlower.numFlowers); 320 | // vertex attributes {position[3], euler_xyz[3], size[1]} 321 | pointFlower.dataArray = new Float32Array(pointFlower.numFlowers * (3 + 3 + 2)); 322 | pointFlower.positionArrayOffset = 0; 323 | pointFlower.eulerArrayOffset = pointFlower.numFlowers * 3; 324 | pointFlower.miscArrayOffset = pointFlower.numFlowers * 6; 325 | 326 | pointFlower.buffer = gl.createBuffer(); 327 | gl.bindBuffer(gl.ARRAY_BUFFER, pointFlower.buffer); 328 | gl.bufferData(gl.ARRAY_BUFFER, pointFlower.dataArray, gl.DYNAMIC_DRAW); 329 | gl.bindBuffer(gl.ARRAY_BUFFER, null); 330 | 331 | unuseShader(pointFlower.program); 332 | 333 | for(var i = 0; i < pointFlower.numFlowers; i++) { 334 | pointFlower.particles[i] = new BlossomParticle(); 335 | } 336 | } 337 | 338 | function initPointFlowers() { 339 | //area 340 | pointFlower.area = Vector3.create(20.0, 20.0, 20.0); 341 | pointFlower.area.x = pointFlower.area.y * renderSpec.aspect; 342 | 343 | pointFlower.fader.x = 10.0; //env fade start 344 | pointFlower.fader.y = pointFlower.area.z; //env fade half 345 | pointFlower.fader.z = 0.1; //near fade start 346 | 347 | //particles 348 | var PI2 = Math.PI * 2.0; 349 | var tmpv3 = Vector3.create(0, 0, 0); 350 | var tmpv = 0; 351 | var symmetryrand = function() {return (Math.random() * 2.0 - 1.0);}; 352 | for(var i = 0; i < pointFlower.numFlowers; i++) { 353 | var tmpprtcl = pointFlower.particles[i]; 354 | 355 | //velocity 356 | tmpv3.x = symmetryrand() * 0.3 + 0.8; 357 | tmpv3.y = symmetryrand() * 0.2 - 1.0; 358 | tmpv3.z = symmetryrand() * 0.3 + 0.5; 359 | Vector3.normalize(tmpv3); 360 | tmpv = 2.0 + Math.random() * 1.0; 361 | tmpprtcl.setVelocity(tmpv3.x * tmpv, tmpv3.y * tmpv, tmpv3.z * tmpv); 362 | 363 | //rotation 364 | tmpprtcl.setRotation( 365 | symmetryrand() * PI2 * 0.5, 366 | symmetryrand() * PI2 * 0.5, 367 | symmetryrand() * PI2 * 0.5 368 | ); 369 | 370 | //position 371 | tmpprtcl.setPosition( 372 | symmetryrand() * pointFlower.area.x, 373 | symmetryrand() * pointFlower.area.y, 374 | symmetryrand() * pointFlower.area.z 375 | ); 376 | 377 | //euler 378 | tmpprtcl.setEulerAngles( 379 | Math.random() * Math.PI * 2.0, 380 | Math.random() * Math.PI * 2.0, 381 | Math.random() * Math.PI * 2.0 382 | ); 383 | 384 | //size 385 | tmpprtcl.setSize(0.9 + Math.random() * 0.1); 386 | } 387 | } 388 | 389 | function renderPointFlowers() { 390 | //update 391 | var PI2 = Math.PI * 2.0; 392 | var limit = [pointFlower.area.x, pointFlower.area.y, pointFlower.area.z]; 393 | var repeatPos = function (prt, cmp, limit) { 394 | if(Math.abs(prt.position[cmp]) - prt.size * 0.5 > limit) { 395 | //out of area 396 | if(prt.position[cmp] > 0) { 397 | prt.position[cmp] -= limit * 2.0; 398 | } 399 | else { 400 | prt.position[cmp] += limit * 2.0; 401 | } 402 | } 403 | }; 404 | var repeatEuler = function (prt, cmp) { 405 | prt.euler[cmp] = prt.euler[cmp] % PI2; 406 | if(prt.euler[cmp] < 0.0) { 407 | prt.euler[cmp] += PI2; 408 | } 409 | }; 410 | 411 | for(var i = 0; i < pointFlower.numFlowers; i++) { 412 | var prtcl = pointFlower.particles[i]; 413 | prtcl.update(timeInfo.delta, timeInfo.elapsed); 414 | repeatPos(prtcl, 0, pointFlower.area.x); 415 | repeatPos(prtcl, 1, pointFlower.area.y); 416 | repeatPos(prtcl, 2, pointFlower.area.z); 417 | repeatEuler(prtcl, 0); 418 | repeatEuler(prtcl, 1); 419 | repeatEuler(prtcl, 2); 420 | 421 | prtcl.alpha = 1.0;//(pointFlower.area.z - prtcl.position[2]) * 0.5; 422 | 423 | prtcl.zkey = (camera.matrix[2] * prtcl.position[0] 424 | + camera.matrix[6] * prtcl.position[1] 425 | + camera.matrix[10] * prtcl.position[2] 426 | + camera.matrix[14]); 427 | } 428 | 429 | // sort 430 | pointFlower.particles.sort(function(p0, p1){return p0.zkey - p1.zkey;}); 431 | 432 | // update data 433 | var ipos = pointFlower.positionArrayOffset; 434 | var ieuler = pointFlower.eulerArrayOffset; 435 | var imisc = pointFlower.miscArrayOffset; 436 | for(var i = 0; i < pointFlower.numFlowers; i++) { 437 | var prtcl = pointFlower.particles[i]; 438 | pointFlower.dataArray[ipos] = prtcl.position[0]; 439 | pointFlower.dataArray[ipos + 1] = prtcl.position[1]; 440 | pointFlower.dataArray[ipos + 2] = prtcl.position[2]; 441 | ipos += 3; 442 | pointFlower.dataArray[ieuler] = prtcl.euler[0]; 443 | pointFlower.dataArray[ieuler + 1] = prtcl.euler[1]; 444 | pointFlower.dataArray[ieuler + 2] = prtcl.euler[2]; 445 | ieuler += 3; 446 | pointFlower.dataArray[imisc] = prtcl.size; 447 | pointFlower.dataArray[imisc + 1] = prtcl.alpha; 448 | imisc += 2; 449 | } 450 | 451 | //draw 452 | gl.enable(gl.BLEND); 453 | //gl.disable(gl.DEPTH_TEST); 454 | gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); 455 | 456 | var prog = pointFlower.program; 457 | useShader(prog); 458 | 459 | gl.uniformMatrix4fv(prog.uniforms.uProjection, false, projection.matrix); 460 | gl.uniformMatrix4fv(prog.uniforms.uModelview, false, camera.matrix); 461 | gl.uniform3fv(prog.uniforms.uResolution, renderSpec.array); 462 | gl.uniform3fv(prog.uniforms.uDOF, Vector3.arrayForm(camera.dof)); 463 | gl.uniform3fv(prog.uniforms.uFade, Vector3.arrayForm(pointFlower.fader)); 464 | 465 | gl.bindBuffer(gl.ARRAY_BUFFER, pointFlower.buffer); 466 | gl.bufferData(gl.ARRAY_BUFFER, pointFlower.dataArray, gl.DYNAMIC_DRAW); 467 | 468 | gl.vertexAttribPointer(prog.attributes.aPosition, 3, gl.FLOAT, false, 0, pointFlower.positionArrayOffset * Float32Array.BYTES_PER_ELEMENT); 469 | gl.vertexAttribPointer(prog.attributes.aEuler, 3, gl.FLOAT, false, 0, pointFlower.eulerArrayOffset * Float32Array.BYTES_PER_ELEMENT); 470 | gl.vertexAttribPointer(prog.attributes.aMisc, 2, gl.FLOAT, false, 0, pointFlower.miscArrayOffset * Float32Array.BYTES_PER_ELEMENT); 471 | 472 | // doubler 473 | for(var i = 1; i < 2; i++) { 474 | var zpos = i * -2.0; 475 | pointFlower.offset[0] = pointFlower.area.x * -1.0; 476 | pointFlower.offset[1] = pointFlower.area.y * -1.0; 477 | pointFlower.offset[2] = pointFlower.area.z * zpos; 478 | gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset); 479 | gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers); 480 | 481 | pointFlower.offset[0] = pointFlower.area.x * -1.0; 482 | pointFlower.offset[1] = pointFlower.area.y * 1.0; 483 | pointFlower.offset[2] = pointFlower.area.z * zpos; 484 | gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset); 485 | gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers); 486 | 487 | pointFlower.offset[0] = pointFlower.area.x * 1.0; 488 | pointFlower.offset[1] = pointFlower.area.y * -1.0; 489 | pointFlower.offset[2] = pointFlower.area.z * zpos; 490 | gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset); 491 | gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers); 492 | 493 | pointFlower.offset[0] = pointFlower.area.x * 1.0; 494 | pointFlower.offset[1] = pointFlower.area.y * 1.0; 495 | pointFlower.offset[2] = pointFlower.area.z * zpos; 496 | gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset); 497 | gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers); 498 | } 499 | 500 | //main 501 | pointFlower.offset[0] = 0.0; 502 | pointFlower.offset[1] = 0.0; 503 | pointFlower.offset[2] = 0.0; 504 | gl.uniform3fv(prog.uniforms.uOffset, pointFlower.offset); 505 | gl.drawArrays(gl.POINT, 0, pointFlower.numFlowers); 506 | 507 | gl.bindBuffer(gl.ARRAY_BUFFER, null); 508 | unuseShader(prog); 509 | 510 | gl.enable(gl.DEPTH_TEST); 511 | gl.disable(gl.BLEND); 512 | } 513 | 514 | // effects 515 | //common util 516 | function createEffectProgram(vtxsrc, frgsrc, exunifs, exattrs) { 517 | var ret = {}; 518 | var unifs = ['uResolution', 'uSrc', 'uDelta']; 519 | if(exunifs) { 520 | unifs = unifs.concat(exunifs); 521 | } 522 | var attrs = ['aPosition']; 523 | if(exattrs) { 524 | attrs = attrs.concat(exattrs); 525 | } 526 | 527 | ret.program = createShader(vtxsrc, frgsrc, unifs, attrs); 528 | useShader(ret.program); 529 | 530 | ret.dataArray = new Float32Array([ 531 | -1.0, -1.0, 532 | 1.0, -1.0, 533 | -1.0, 1.0, 534 | 1.0, 1.0 535 | ]); 536 | ret.buffer = gl.createBuffer(); 537 | gl.bindBuffer(gl.ARRAY_BUFFER, ret.buffer); 538 | gl.bufferData(gl.ARRAY_BUFFER, ret.dataArray, gl.STATIC_DRAW); 539 | 540 | gl.bindBuffer(gl.ARRAY_BUFFER, null); 541 | unuseShader(ret.program); 542 | 543 | return ret; 544 | } 545 | 546 | // basic usage 547 | // useEffect(prog, srctex({'texture':texid, 'dtxArray':(f32)[dtx, dty]})); //basic initialize 548 | // gl.uniform**(...); //additional uniforms 549 | // drawEffect() 550 | // unuseEffect(prog) 551 | // TEXTURE0 makes src 552 | function useEffect(fxobj, srctex) { 553 | var prog = fxobj.program; 554 | useShader(prog); 555 | gl.uniform3fv(prog.uniforms.uResolution, renderSpec.array); 556 | 557 | if(srctex != null) { 558 | gl.uniform2fv(prog.uniforms.uDelta, srctex.dtxArray); 559 | gl.uniform1i(prog.uniforms.uSrc, 0); 560 | 561 | gl.activeTexture(gl.TEXTURE0); 562 | gl.bindTexture(gl.TEXTURE_2D, srctex.texture); 563 | } 564 | } 565 | function drawEffect(fxobj) { 566 | gl.bindBuffer(gl.ARRAY_BUFFER, fxobj.buffer); 567 | gl.vertexAttribPointer(fxobj.program.attributes.aPosition, 2, gl.FLOAT, false, 0, 0); 568 | gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); 569 | } 570 | function unuseEffect(fxobj) { 571 | unuseShader(fxobj.program); 572 | } 573 | 574 | var effectLib = {}; 575 | function createEffectLib() { 576 | 577 | var vtxsrc, frgsrc; 578 | //common 579 | var cmnvtxsrc = document.getElementById("fx_common_vsh").textContent; 580 | 581 | //background 582 | frgsrc = document.getElementById("bg_fsh").textContent; 583 | effectLib.sceneBg = createEffectProgram(cmnvtxsrc, frgsrc, ['uTimes'], null); 584 | 585 | // make brightpixels buffer 586 | frgsrc = document.getElementById("fx_brightbuf_fsh").textContent; 587 | effectLib.mkBrightBuf = createEffectProgram(cmnvtxsrc, frgsrc, null, null); 588 | 589 | // direction blur 590 | frgsrc = document.getElementById("fx_dirblur_r4_fsh").textContent; 591 | effectLib.dirBlur = createEffectProgram(cmnvtxsrc, frgsrc, ['uBlurDir'], null); 592 | 593 | //final composite 594 | vtxsrc = document.getElementById("pp_final_vsh").textContent; 595 | frgsrc = document.getElementById("pp_final_fsh").textContent; 596 | effectLib.finalComp = createEffectProgram(vtxsrc, frgsrc, ['uBloom'], null); 597 | } 598 | 599 | // background 600 | function createBackground() { 601 | //console.log("create background"); 602 | } 603 | function initBackground() { 604 | //console.log("init background"); 605 | } 606 | function renderBackground() { 607 | gl.disable(gl.DEPTH_TEST); 608 | 609 | useEffect(effectLib.sceneBg, null); 610 | gl.uniform2f(effectLib.sceneBg.program.uniforms.uTimes, timeInfo.elapsed, timeInfo.delta); 611 | drawEffect(effectLib.sceneBg); 612 | unuseEffect(effectLib.sceneBg); 613 | 614 | gl.enable(gl.DEPTH_TEST); 615 | } 616 | 617 | // post process 618 | var postProcess = {}; 619 | function createPostProcess() { 620 | //console.log("create post process"); 621 | } 622 | function initPostProcess() { 623 | //console.log("init post process"); 624 | } 625 | 626 | function renderPostProcess() { 627 | gl.enable(gl.TEXTURE_2D); 628 | gl.disable(gl.DEPTH_TEST); 629 | var bindRT = function (rt, isclear) { 630 | gl.bindFramebuffer(gl.FRAMEBUFFER, rt.frameBuffer); 631 | gl.viewport(0, 0, rt.width, rt.height); 632 | if(isclear) { 633 | gl.clearColor(0, 0, 0, 0); 634 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 635 | } 636 | }; 637 | 638 | //make bright buff 639 | bindRT(renderSpec.wHalfRT0, true); 640 | useEffect(effectLib.mkBrightBuf, renderSpec.mainRT); 641 | drawEffect(effectLib.mkBrightBuf); 642 | unuseEffect(effectLib.mkBrightBuf); 643 | 644 | // make bloom 645 | for(var i = 0; i < 2; i++) { 646 | var p = 1.5 + 1 * i; 647 | var s = 2.0 + 1 * i; 648 | bindRT(renderSpec.wHalfRT1, true); 649 | useEffect(effectLib.dirBlur, renderSpec.wHalfRT0); 650 | gl.uniform4f(effectLib.dirBlur.program.uniforms.uBlurDir, p, 0.0, s, 0.0); 651 | drawEffect(effectLib.dirBlur); 652 | unuseEffect(effectLib.dirBlur); 653 | 654 | bindRT(renderSpec.wHalfRT0, true); 655 | useEffect(effectLib.dirBlur, renderSpec.wHalfRT1); 656 | gl.uniform4f(effectLib.dirBlur.program.uniforms.uBlurDir, 0.0, p, 0.0, s); 657 | drawEffect(effectLib.dirBlur); 658 | unuseEffect(effectLib.dirBlur); 659 | } 660 | 661 | //display 662 | gl.bindFramebuffer(gl.FRAMEBUFFER, null); 663 | gl.viewport(0, 0, renderSpec.width, renderSpec.height); 664 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 665 | 666 | useEffect(effectLib.finalComp, renderSpec.mainRT); 667 | gl.uniform1i(effectLib.finalComp.program.uniforms.uBloom, 1); 668 | gl.activeTexture(gl.TEXTURE1); 669 | gl.bindTexture(gl.TEXTURE_2D, renderSpec.wHalfRT0.texture); 670 | drawEffect(effectLib.finalComp); 671 | unuseEffect(effectLib.finalComp); 672 | 673 | gl.enable(gl.DEPTH_TEST); 674 | } 675 | 676 | ///// 677 | var SceneEnv = {}; 678 | function createScene() { 679 | createEffectLib(); 680 | createBackground(); 681 | createPointFlowers(); 682 | createPostProcess(); 683 | sceneStandBy = true; 684 | } 685 | 686 | function initScene() { 687 | initBackground(); 688 | initPointFlowers(); 689 | initPostProcess(); 690 | 691 | //camera.position.z = 17.320508; 692 | camera.position.z = pointFlower.area.z + projection.nearfar[0]; 693 | projection.angle = Math.atan2(pointFlower.area.y, camera.position.z + pointFlower.area.z) * 180.0 / Math.PI * 2.0; 694 | Matrix44.loadProjection(projection.matrix, renderSpec.aspect, projection.angle, projection.nearfar[0], projection.nearfar[1]); 695 | } 696 | 697 | function renderScene() { 698 | //draw 699 | Matrix44.loadLookAt(camera.matrix, camera.position, camera.lookat, camera.up); 700 | 701 | gl.enable(gl.DEPTH_TEST); 702 | 703 | //gl.bindFramebuffer(gl.FRAMEBUFFER, null); 704 | gl.bindFramebuffer(gl.FRAMEBUFFER, renderSpec.mainRT.frameBuffer); 705 | gl.viewport(0, 0, renderSpec.mainRT.width, renderSpec.mainRT.height); 706 | gl.clearColor(0.005, 0, 0.05, 0); 707 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 708 | 709 | renderBackground(); 710 | renderPointFlowers(); 711 | renderPostProcess(); 712 | } 713 | 714 | function onResize(e) { 715 | makeCanvasFullScreen(document.getElementById("sakura")); 716 | setViewports(); 717 | if(sceneStandBy) { 718 | initScene(); 719 | } 720 | } 721 | 722 | function setViewports() { 723 | renderSpec.setSize(gl.canvas.width, gl.canvas.height); 724 | 725 | gl.clearColor(0.2, 0.2, 0.5, 1.0); 726 | gl.viewport(0, 0, renderSpec.width, renderSpec.height); 727 | 728 | var rtfunc = function (rtname, rtw, rth) { 729 | var rt = renderSpec[rtname]; 730 | if(rt) deleteRenderTarget(rt); 731 | renderSpec[rtname] = createRenderTarget(rtw, rth); 732 | }; 733 | rtfunc('mainRT', renderSpec.width, renderSpec.height); 734 | rtfunc('wFullRT0', renderSpec.width, renderSpec.height); 735 | rtfunc('wFullRT1', renderSpec.width, renderSpec.height); 736 | rtfunc('wHalfRT0', renderSpec.halfWidth, renderSpec.halfHeight); 737 | rtfunc('wHalfRT1', renderSpec.halfWidth, renderSpec.halfHeight); 738 | } 739 | 740 | function render() { 741 | renderScene(); 742 | } 743 | 744 | var animating = true; 745 | 746 | 747 | function stepAnimation() { 748 | if(!animating) animate(); 749 | } 750 | 751 | function animate() { 752 | var curdate = new Date(); 753 | timeInfo.elapsed = (curdate - timeInfo.start) / 1000.0; 754 | timeInfo.delta = (curdate - timeInfo.prev) / 1000.0; 755 | timeInfo.prev = curdate; 756 | 757 | if(animating) requestAnimationFrame(animate); 758 | render(); 759 | } 760 | 761 | function makeCanvasFullScreen(canvas) { 762 | var b = document.body; 763 | var d = document.documentElement; 764 | var fullw = Math.max(b.clientWidth , b.scrollWidth, d.scrollWidth, d.clientWidth); 765 | var fullh = Math.max(b.clientHeight , b.scrollHeight, d.scrollHeight, d.clientHeight); 766 | canvas.width = fullw; 767 | canvas.height = fullh; 768 | } 769 | 770 | window.addEventListener('load', function(e) { 771 | var canvas = document.getElementById("sakura"); 772 | try { 773 | makeCanvasFullScreen(canvas); 774 | gl = canvas.getContext('experimental-webgl'); 775 | } catch(e) { 776 | alert("WebGL not supported." + e); 777 | console.error(e); 778 | return; 779 | } 780 | 781 | window.addEventListener('resize', onResize); 782 | 783 | setViewports(); 784 | createScene(); 785 | initScene(); 786 | 787 | timeInfo.start = new Date(); 788 | timeInfo.prev = timeInfo.start; 789 | animate(); 790 | }); 791 | 792 | //set window.requestAnimationFrame 793 | (function (w, r) { 794 | w['r'+r] = w['r'+r] || w['webkitR'+r] || w['mozR'+r] || w['msR'+r] || w['oR'+r] || function(c){ w.setTimeout(c, 1000 / 60); }; 795 | })(window, 'requestAnimationFrame'); -------------------------------------------------------------------------------- /5-GlassmorphismLogin/login.css: -------------------------------------------------------------------------------- 1 | *{ 2 | outline: none; 3 | /* 让输入框被选中后没有默认框框 */ 4 | user-select: none; 5 | /* 用户不能选中文本,整体性更强 */ 6 | } 7 | 8 | body{ 9 | margin: 0; 10 | padding: 0; 11 | /* 让页面外围没有一圈内边距 */ 12 | 13 | background: url(./wallpaper.png); 14 | /* 尽量使用相对位置或图床链接 */ 15 | background-size: cover; 16 | background-attachment: fixed; 17 | } 18 | 19 | form{ 20 | background-color: rgba(255, 255, 255, .3); 21 | width: 400px; 22 | height: 400px; 23 | border-radius: 30px; 24 | 25 | /* 一种水平+垂直的居中定位方式 */ 26 | position: absolute; 27 | top: 50%; 28 | left: 50%; 29 | transform: translate(-50%, -50%); 30 | /* 这个比上次人工队计算宽高一半要好 */ 31 | 32 | /* 注入灵魂 */ 33 | backdrop-filter: blur(3px); 34 | border-left: 2px solid rgba(255, 255, 255, .3); 35 | border-top: 2px solid rgba(255, 255, 255, .3); 36 | box-shadow: 2px 2px 10px rgba(0, 0, 0, .2); 37 | 38 | text-align: center; 39 | } 40 | 41 | h1{ 42 | margin: 20px; 43 | 44 | font-weight: 400; 45 | /* 毛玻璃的话,标题比扁平 字重小一点为好 */ 46 | font-size: 88px; 47 | font-family: "Berlin Sans FB"; 48 | } 49 | .tt{ 50 | color: white; 51 | text-shadow: 2px 2px 4px rgba(0, 0, 0, .2); 52 | opacity: 0.9; 53 | } 54 | 55 | input{ 56 | border: none; 57 | width: 80%; 58 | font-size: 22px; 59 | padding: 10px; 60 | margin-bottom: 32px; 61 | border-radius: 16px; 62 | background-color: transparent; 63 | 64 | /* 注入灵魂 */ 65 | backdrop-filter: blur(3px); 66 | border-left: 2px solid rgba(255, 255, 255, .3); 67 | border-top: 2px solid rgba(255, 255, 255, .3); 68 | box-shadow: 2px 2px 2px rgba(0, 0, 0, .2); 69 | 70 | text-shadow: 2px 2px 2px rgba(0, 0, 0, .2); 71 | font-family: "Berlin Sans FB"; 72 | color: white; 73 | /* 只能控制输入的文本的颜色 */ 74 | } 75 | /* 而placeholder要单独设置属性 */ 76 | ::placeholder{ 77 | color: white; 78 | opacity: 0.8; 79 | } 80 | 81 | .btn{ 82 | width: 240px; 83 | font-size: 34px; 84 | font-weight: bold; 85 | margin-top: 10px; 86 | cursor: pointer; 87 | } 88 | 89 | input:focus{ 90 | border: none; 91 | background-color: rgba(255, 255, 255, .1); 92 | /* 注入灵魂 */ 93 | text-shadow: 1px 1px 2px rgba(0, 0, 0, .2); 94 | border-right: 2px solid rgba(255, 255, 255, .3); 95 | border-bottom: 2px solid rgba(255, 255, 255, .3); 96 | box-shadow:inset 2px 2px 2px rgba(0, 0, 0, .2); 97 | } -------------------------------------------------------------------------------- /5-GlassmorphismLogin/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 毛玻璃拟态登录界面 8 | 9 | 10 | 11 |
12 |

BBSBB

13 | 14 | 15 | 16 |
17 | 18 | -------------------------------------------------------------------------------- /5-GlassmorphismLogin/wallpaper.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AuroraTea/Web/e8f6e747819114215d9f37273dd71bfd7875b535/5-GlassmorphismLogin/wallpaper.png -------------------------------------------------------------------------------- /5-GlassmorphismLogin/wallpaper2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AuroraTea/Web/e8f6e747819114215d9f37273dd71bfd7875b535/5-GlassmorphismLogin/wallpaper2.png -------------------------------------------------------------------------------- /6-CoverWithBand/band.css: -------------------------------------------------------------------------------- 1 | body{ 2 | background: #ececec; 3 | } 4 | 5 | .box{ 6 | position: absolute; 7 | left: 50%; 8 | top: 50%; 9 | transform: translate(-50%, -50%); 10 | 11 | background: #fff; 12 | width: 600px; 13 | height: 400px; 14 | box-shadow: -10px 10px 10px rgba(0,0,0,.1); 15 | } 16 | 17 | .cover-text{ 18 | margin: 20px; 19 | margin-top: 100px; 20 | text-align: center; 21 | font-size: 80px; 22 | font-weight: bold; 23 | color: #939393; 24 | } 25 | 26 | .band span{ 27 | background: #3699d5; 28 | /* 视频中的CSS */ 29 | /* background: #4E5C93; */ 30 | /* 视频中的PHP */ 31 | /* background: #FA8A2A; */ 32 | /* 视频中的SVG */ 33 | /* background: linear-gradient(to right, #355BC9, #6D38D7); */ 34 | /* 视频中的Unboxing */ 35 | 36 | color: #fff; 37 | 38 | width: 225px; 39 | font-size: 24px; 40 | font-weight: bold; 41 | padding: 8px 0; 42 | 43 | position: absolute; 44 | transform: rotate(45deg); 45 | left: -25px; 46 | top: 30px; 47 | text-shadow:0 1px 1px rgba(0,0,0,.2); 48 | text-align: center; 49 | box-shadow:0 10px 10px rgba(0,0,0,.1); 50 | /* 这里其实是有所瑕疵的 */ 51 | /* box-shadow:0 10px 10px black; 52 | 作为阴影 形状是不对的 */ 53 | } 54 | 55 | .band{ 56 | position: absolute; 57 | width: 150px; 58 | height: 150px; 59 | overflow: hidden; 60 | top: -10px; 61 | right: -10px; 62 | } 63 | .band::before, 64 | .band::after{ 65 | border: 5px solid #2880b8; 66 | /* 视频中的CSS */ 67 | /* border: 5px solid #434B77; */ 68 | /* 视频中的PHP,Unboxing同 */ 69 | /* border: 5px solid #E35B1B; */ 70 | /* 视频中的SVG */ 71 | 72 | content: ''; 73 | /* 要加content伪元素才能显示 */ 74 | position: absolute; 75 | border-top-color: transparent; 76 | border-right-color: transparent; 77 | /* 来形成三角形 */ 78 | } 79 | .band::after{ 80 | bottom: 0; 81 | right: 0; 82 | } -------------------------------------------------------------------------------- /6-CoverWithBand/cover.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Cover for Steven 8 | 9 | 10 | 11 |
12 |

蹭Steven热度专用封面

13 |
14 | CSS 15 |
16 |
17 | 18 | -------------------------------------------------------------------------------- /7-LovelyClock/clock.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css?family=Kanit:900"); 2 | 3 | body{ 4 | background: #EACCCC; 5 | user-select: none; 6 | } 7 | 8 | .clock{ 9 | position: absolute; 10 | top: 50%; 11 | left: 50%; 12 | transform: translate(-50%, -50%); 13 | 14 | width: 452px; 15 | /* 此处为油纸包里的UP精密计算得出,不过其实一开始就采用flex布局或者grid布局效果应该会更好,留待大家尝试一二. */ 16 | } 17 | .clock p{ 18 | width: 70px; 19 | text-align: center; 20 | 21 | font-family: Kanit; 22 | font-size: 100px; 23 | color: #fff; 24 | /* 以白桃粉为基础,利用一些小学二年级的简单计算易得: */ 25 | text-shadow: 26 | 0 1px 0 #deafaf, 27 | 0 2px 0 #dba8a8, 28 | 0 3px 0 #d8a1a1, 29 | 0 4px 0 #d59999, 30 | 0 5px 0 #d29292, 31 | 0 6px 0 #cf8b8b, 32 | 0 7px 0 #cc8484, 33 | 0 8px 0 #c97d7d, 34 | 0 0 5px rgba(231, 156, 156, 0.05), 35 | 0 -1px 3px rgba(231, 156, 156, 0.2), 36 | 0 9px 9px rgba(231, 156, 156, 0.3), 37 | 0 12px 12px rgba(231, 156, 156, 0.3), 38 | 0 15px 15px rgba(231, 156, 156, 0.3); 39 | /* 突然觉得不3D也挺好看的,你们怎么看呢? */ 40 | 41 | float: left; 42 | margin: -3px; 43 | /* 此处感谢 react和vue可兼得 提供的思路 */ 44 | } 45 | .clock p:nth-child(3n){ 46 | width: 40px; 47 | } -------------------------------------------------------------------------------- /7-LovelyClock/clock.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 甜糖白桃可爱风立体字时钟 9 | 10 | 11 |
12 |

13 |

14 |

:

15 |

16 |

17 |

:

18 |

19 |

20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /7-LovelyClock/clock.js: -------------------------------------------------------------------------------- 1 | function myTime() { 2 | let time = new Date(); 3 | let hh = time.getHours(); 4 | let mm = time.getMinutes(); 5 | let ss = time.getSeconds(); 6 | 7 | document.getElementById("1").innerText = Math.floor(hh / 10); 8 | // 因为js的/不是整除而是得到浮点数 9 | // 另外如果是喜欢看8:00而非08:00的这里可以做个判断,比如: 10 | // document.getElementById("1").innerText = hh<10?null:Math.floor(hh / 10); 11 | document.getElementById("2").innerText = hh % 10; 12 | document.getElementById("4").innerText = Math.floor(mm / 10); 13 | document.getElementById("5").innerText = mm % 10; 14 | document.getElementById("7").innerText = Math.floor(ss / 10); 15 | document.getElementById("8").innerText = ss % 10; 16 | } 17 | myTime(); 18 | setInterval(myTime,1000); -------------------------------------------------------------------------------- /8-DigitalClock/clock.css: -------------------------------------------------------------------------------- 1 | /* 上次有人问最上面是啥 2 | 这里其实是引用了谷歌字体呀 3 | 上次是非等宽字体等宽显示,这次我们直接选用等宽字体 */ 4 | @import url('https://fonts.googleapis.com/css2?family=Share+Tech+Mono&display=swap'); 5 | /* 这里的display=swap其实是个好东西,会在字体没加载完成的时候优先显示后备字体,此时选一个大家电脑上,客户端电脑上会有的字体就显示的很快,但是等下我会偷懒不这么做*/ 6 | 7 | body{ 8 | background: radial-gradient(#0A2E38, #000 70%); 9 | background-color: #0a2e38; 10 | height: 100vh; 11 | overflow: hidden; 12 | user-select: none; 13 | display: flex; 14 | justify-content: center; 15 | align-items: center; 16 | } 17 | 18 | #clock{ 19 | color: #fff; 20 | font-size: 100px; 21 | font-family: 'Share Tech Mono'; 22 | text-shadow: 0 0 20px #0AAFE6, 0 2px 0 #DAF6FF; 23 | } -------------------------------------------------------------------------------- /8-DigitalClock/clock.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 数码风时钟 8 | 9 | 10 | 11 |
12 | 13 | 14 | -------------------------------------------------------------------------------- /8-DigitalClock/clock.js: -------------------------------------------------------------------------------- 1 | function myTime(){ 2 | const time = new Date(); 3 | const hh = time.getHours(); 4 | const mm = time.getMinutes();//没有补全烦死了 5 | const ss = time.getSeconds(); 6 | //这里用const可以不用去判断作用域,比用let和var的性能要好 7 | // 而且也没必要用变量嘛,上个视频不应该用let的 8 | 9 | document.getElementById('clock').innerText = Math.floor(hh / 10) + (hh % 10 + ':') + Math.floor(mm / 10) + mm % 10 + ':' + Math.floor(ss / 10) + ss % 10; 10 | //因为js的/不是整除而是会求出浮点数 11 | //所以这里我们要用Math.floor()方法来向下取整 12 | }//知道是为什么吗?~可以打在弹幕里哦~ 13 | myTime(); 14 | setInterval(myTime, 1000); -------------------------------------------------------------------------------- /9-simpleShop/cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AuroraTea/Web/e8f6e747819114215d9f37273dd71bfd7875b535/9-simpleShop/cover.png -------------------------------------------------------------------------------- /9-simpleShop/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AuroraTea/Web/e8f6e747819114215d9f37273dd71bfd7875b535/9-simpleShop/icon.png -------------------------------------------------------------------------------- /9-simpleShop/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 这里是标签页标题啦 8 | 9 | 10 | 11 | 12 |
13 | 20 |
21 | 22 | 23 | 甜糖白桃 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 | 32 | -------------------------------------------------------------------------------- /9-simpleShop/style.css: -------------------------------------------------------------------------------- 1 | body{ 2 | margin: 0; 3 | background-color: #f5f5f5; 4 | 5 | display: flex; 6 | flex-direction: column; 7 | height: 100vh; 8 | /* 用flex划空间需要父元素有个具体的尺寸 */ 9 | 10 | -webkit-tap-highlight-color: transparent; 11 | } 12 | 13 | header{ 14 | height: 40px; 15 | background-color: #333; 16 | flex-shrink: 0; 17 | /* 默认值为1 */ 18 | } 19 | 20 | nav{ 21 | border-bottom: 1px solid #e6e6e6; 22 | height: 80px; 23 | 24 | display: flex; 25 | justify-content: center; 26 | } 27 | nav a{ 28 | text-decoration: none; 29 | /* 去掉下划线 */ 30 | font-size: 20px; 31 | color: #000; 32 | padding: 30px 10px; 33 | margin: 0 20px; 34 | /* 这样可以做出线分开的感觉 */ 35 | } 36 | nav a:hover{ 37 | color: #ff6700; 38 | border-bottom: 3px solid #ff6700; 39 | transition: all .2s; 40 | -webkit-transition: all .2s; 41 | -moz-transition: all .2s; 42 | -ms-transition: all .2s; 43 | -o-transition: all .2s; 44 | /*这些是兼容性代码*//*自动生成是靠的Autoprefixer插件*//*兼容这些浏览器的老版本,在那些版本里这是实验性功能*/; 45 | } 46 | 47 | .showcase{ 48 | flex-grow: 1; 49 | /* 意思是header:nav:div.showcase:footer=0:0:1:0 */ 50 | margin-top: 20px; 51 | 52 | /* 之前的空行也是,为的是分开对自己的设置和对子元素的设置,好读 */ 53 | display: flex; 54 | justify-content: center; 55 | flex-wrap: wrap; 56 | align-content: start; 57 | /* 如果.showcase a的个数很少的话这句话是必要的哦 */ 58 | } 59 | .showcase a{ 60 | width: 270px; 61 | /*width: 150px; 62 | */height: 180px; 63 | background-color: #fff; 64 | margin: 20px; 65 | 66 | transition-property: transform, box-shadow; 67 | transition-duration: .3s, .3s; 68 | /* 特定多个对象的话,不能用transition的嘞 */ 69 | /* transition本身就是tp和tduration和tdelay的简写来着 */ 70 | 71 | text-decoration: none; 72 | } 73 | .showcase a:hover{ 74 | transform: translateY(-8px); 75 | -webkit-transform: translateY(-8px); 76 | -moz-transform: translateY(-8px); 77 | -ms-transform: translateY(-8px); 78 | -o-transform: translateY(-8px); 79 | box-shadow: 0 10px 20px rgba(0, 0, 0, .1); 80 | } 81 | /* hover在移动端的效果不大好 */ 82 | /* 可以用@media给移动端来点特殊效果 */ 83 | /* 但是本视频就先不涉及@media了 */ 84 | .showcase a img{ 85 | width: 270px; 86 | } 87 | .showcase a span{ 88 | display: block; 89 | text-align: center; 90 | color: #595959; 91 | } 92 | 93 | footer{ 94 | text-align: center; 95 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Web 2 | 发在B站上的视频对应的源代码,有些内容不是原创的会在代码中注释。 3 | 我的B站:https://space.bilibili.com/24100898 4 | --------------------------------------------------------------------------------