最近在使用react 写个人站点,发现项目一开始加载有很大一段白屏,觉得这样不是很好,需要优化一下,然后项目里面使用的是 antd 的 spin, 所以首页就使用 html + css 来实现一个
效果
分析
主要分为以下几个部分:
1.loading 需要居中
居中的方法有很多,父相子绝, 弹性盒模型 等。 antd 官方是这么实现的:
position: absolute; left: 50%; top: 50%; bottom: 0; right: 0; transform: translate(-50%, -50%); display: flex; justify-content: center; align-items: center; flex-direction: column; background-color: #f0ebeb; width: 100%; height: 100%; cursor: pointer; 复制代码
2.内容区域
内容区域分为两个部分,一个 旋转的部分, 另一个是文字区域,这里布局也很简单,直接两个block, 或者 inline-block,就行
旋转区域
看到是在旋转,那么肯定是需要一个容器包裹着四个标签,然后最外面的容器来进行旋转,这个旋转角度我们可以看到是45deg, 但是如果你直接写旋转 45deg 的话,会发现动画是非常硬,一点也不平滑
解决办法
解决办法也有多种:
1.在旋转的时候加上transition来进行过渡
2.旋转的角度是(360 + 45)deg 这样来旋转就会平滑了,时间的话,平均每个0.4s, 那么就是 1.2s, 这里为啥要0.4s呢, 因为等一下还有一个闪烁的动画
闪烁怎么做
闪烁的话其实就是一开始 opacity 小一点,然后在旋转到当前的时候 opacity为1。 这里有一个细节,那就是每一个点执行动画的时间是不一样的, 所以每一个点都要基于上一个点执行动画延迟 0.4s 就可以实现了
文字区域
文字区域相信没有难度
源码如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>手动实现antd spin 的一个loading</title> <style> .my-loading-container { position: absolute; left: 50%; top: 50%; bottom: 0; right: 0; transform: translate(-50%, -50%); display: flex; justify-content: center; align-items: center; flex-direction: column; background-color: #f0ebeb; width: 100%; height: 100%; cursor: pointer; font-size: 14px; } .my-loading-span { position: relative; display: inline-block; font-size: 32px; width: 1em; height: 1em; transform: rotateZ(45deg); transition: transform .3s cubic-bezier(.78, .14, .15, .86); animation: Rotate45 1.2s infinite linear; } .my-loading-span>i { height: 14px; width: 14px; background-color: #00D8FF; display: block; position: absolute; border-radius: 100%; transform: scale(.75); transform-origin: 50% 50%; opacity: .3; animation: myAnimationMove 1s infinite linear alternate; } .my-loading-span:nth-child(1) { top: 0; left: 0; } .my-loading-span :nth-child(2) { top: 0; right: 0; animation-delay: .4s; } .my-loading-span :nth-child(3) { bottom: 0; right: 0; animation-delay: .8s; } .my-loading-span :nth-child(4) { left: 0; bottom: 0; animation-delay: 1.2s; } .my-loading-container>.my-text-container { padding-top: 5px; text-shadow: 0 1px 2px #fff; color: #00D8FF; font-variant: tabular-nums; font-feature-settings: 'tnum'; font-size: 14px; } @keyframes Rotate45 { to { transform: rotate(405deg); } } @keyframes myAnimationMove { to { opacity: 1; } } </style> </head> <body> <div class="my-loading-container" id="myLoadingContainer"> <span class="my-loading-span"> <i></i> <i></i> <i></i> <i></i> </span> <div class="my-text-container"> Loading... </div> </div> </body> </html> 复制代码