前言
一些大牛的demo使人不明觉厉,我们通过分析代码了解他们的思路,从而充实自己,每日一练
通过HTML和css生成加载动画
思路步骤
分析动画的每一个构建单元
![](https://img-blog.csdnimg.cn/img_convert/deb8bcf44ad3003483cfd24d8ce20d33.gif)
一个大盒子里面有n多小盒子,每一个小盒子又有一个黑球一个白球,然后通过定位使得每一个小盒子到达指定位置,最后用动画实现效果
创建盒子
使用div.dot*36生成每一项小盒子
给定样式,通过定位使每个子元素到达指定位置
使用定位和旋转使得每一项到达指定位置
通过 ::before 和 ::after 生成黑白小球
使用伪元素生成小球
给黑白两球设置动画
把黑白两球的运动分为上下前后四步
白球四步:从下方开始,往后方偏中运动,往上到最上,再前方偏中运动,最后回到起点,循环往复
黑球四步:从上方开始,往前方偏中运动,往下到最下,再后方偏中运动,最后回到起点,循环往复
通过动画延时达到最终效果
使用动画延时达到最终效果
完整代码
<template>
<!-- 盒子 -->
<div class='loading'>
<!-- div.dot*36生成每一项 -->
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
</div>
</template>
// 使用scss更方便,首先定义变量
<style lang="scss">
page{
background: #55ffff; // 背景色
}
$containerSize:150px; // 容器尺寸
$ballSize:10px; // 小球尺寸
$dotn:36; // 小球数量
$pdeg:360deg / $dotn; // 旋转度数
$ani-duration:2000ms; // 动画时间
.loading{
width: $containerSize;
height: $containerSize;
margin: 50px auto;
position: relative;
border-radius: 50%;
.dot{
position: absolute;
left: 50%;
top: 50%;
width: $ballSize;
height: $ballSize;
margin-left: -$ballSize / 2;
margin-top: -$ballSize / 2;
// 下面两行代码达到3d效果,小球在靠近前方时感官变大
perspective: 50px;
transform-style: preserve-3d;
&::before,&::after{ // 黑白球共同样式
content: '';
position: absolute;
width: 100%;
height: 100%;
border-radius: 50%;
}
&::before{ // 黑球单独样式
background: #000;
top: -100%;
animation: moveBlack $ani-duration infinite;
}
&::after{ // 白球单独样式
background: #fff;
top: 100%;
animation: moveWhite $ani-duration infinite;
}
}
}
// 白球动画
@keyframes moveWhite{
0%{
animation-timing-function: ease-in;
}
25%{
transform: translate3d(0, -100%, -$ballSize);
animation-timing-function: ease-out;
}
50%{
transform: translate3d(0, -200%, 0);
animation-timing-function: ease-in;
}
75%{
transform: translate3d(0, -100%, $ballSize);
animation-timing-function: ease-out;
}
}
// 黑球动画
@keyframes moveBlack{
0%{
animation-timing-function: ease-in;
}
25%{
transform: translate3d(0, 100%, $ballSize);
animation-timing-function: ease-out;
}
50%{
transform: translate3d(0, 200%, 0);
animation-timing-function: ease-in;
}
75%{
transform: translate3d(0, 100%, -$ballSize);
animation-timing-function: ease-out;
}
}
// 遍历赋予样式
@for $var from 1 through $dotn {
.dot:nth-child(#{$var}){
transform: rotate($pdeg * $var) translateY(-$containerSize / 2);
// 动画延时
&::before,&::after{
animation-delay: -$ani-duration / $dotn * 9 * $var;
}
}
}
</style>