前言
晚上躺床上刷视频的时候看到有个前端大佬写了一个loading,这是效果:
感觉也挺有意思哈,要不自己也写一个,学习 + 复习 两不误。
但是又因为太晚了,不想起来开整,那就留到第二天空了再整。第二天借中午休息这点时间来完成头天晚上立下的falg,最后再通过这篇笔记来记录一下里面的一些知识点。
结构
看他这个视频,css部分采用的是less写的,刚好我有个平时用来实现一些项目功能或者自己感兴趣的一个react 搭建的模板,然后就在这个基础上创建了个页面来实现这个loading效果。
废话不多说,开整。
html
<div className='wrp'>
<div className='loading'>
<div className='dot'></div>
<div className='dot'></div>
<div className='dot'></div>
<div className='dot'></div>
<div className='dot'></div>
<div className='dot'></div>
<div className='dot'></div>
<div className='dot'></div>
<div className='dot'></div>
<div className='dot'></div>
<div className='dot'></div>
<div className='dot'></div>
<div className='dot'></div>
<div className='dot'></div>
<div className='dot'></div>
<div className='dot'></div>
<div className='dot'></div>
<div className='dot'></div>
<div className='dot'></div>
<div className='dot'></div>
<div className='dot'></div>
<div className='dot'></div>
<div className='dot'></div>
<div className='dot'></div>
<div className='dot'></div>
<div className='dot'></div>
<div className='dot'></div>
<div className='dot'></div>
<div className='dot'></div>
<div className='dot'></div>
<div className='dot'></div>
<div className='dot'></div>
<div className='dot'></div>
<div className='dot'></div>
<div className='dot'></div>
<div className='dot'></div>
</div>
</div>
最底层子节点共计36个,按照一圈360°来讲,正好每个分10°,便于计算,没啥特别的意义,可以根据自己的喜好需求来定义到底可以展示多少个。
css
@ballSize: 10px;
@containerSize: 150px;
@ballNum: 36;
@pdeg: 10deg;
@ani-duration: 2000ms;
.wrp {
width: 100%;
height: 100%;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
background-color: rgb(105, 207, 247);
.loading {
width: @containerSize;
height: @containerSize;
// border: 1px solid #fff;
border-radius: 50%;
position: relative;
.dot {
position: absolute;
top: 50%;
left: 50%;
width: @ballSize;
height: @ballSize;
margin-left: -@ballSize/2;
margin-top: -@ballSize/2;
// background-color: red;
perspective: 70px;
transform-style: preserve-3d;
&::before,&::after{
content: '';
width: 100%;
height: 100%;
border-radius: 50%;
position: absolute;
}
&::before{
background-color: #000;
top: -100%;
// 重要 -- 动画
animation: moveBlack @ani-duration infinite;
}
&::after{
background-color: #fff;
top: 100%;
// 重要 -- 动画
animation: moveWhite @ani-duration infinite;
}
}
// 重要 -- 循环
.loop(@i) when (@i <=@ballNum) {
.dot:nth-child(@{i}) {
transform: rotate(@pdeg * (@i - 1)) translateY(-@containerSize/2);
color: red;
// 重要 -- 动画延时
&::before,&::after{
animation-delay: -@ani-duration / @ballNum * 6 * @i;
}
}
.loop(@i + 1);
}
.loop(1);
}
}
// 重要 -- 沿着Y轴旋转
@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;
}
}
// 重要 -- 沿着Y轴旋转
@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;
}
}
知识点总结
-
定位
- 绝对定位:relative
- 相对定位:absolute
-
伪元素
::before和::after是伪元素。
需要注意的是CSS3中为了与伪类做区别,伪元素采用双冒号的写法;但因为兼容性的问题,所以现在大部分还是统一的单冒号,比如 :first-line、:first-letter、:before、:after
等,CSS3中引入的伪元素不允许用单冒号这种写法。
-
less定义变量
@ballSize: 10px;
参照上面的示例,左侧以@开头,紧跟着定义的变量名称,右侧则是声明变量所对应的值,最后需要跟上分好(可以根据自己的需求进行配置)。
-
循环
// 重要 -- 循环
.loop(@i) when (@i <=@ballNum) {
// 循环事件中函数需要处理的主体
.dot:nth-child(@{i}) {
transform: rotate(@pdeg * (@i - 1)) translateY(-@containerSize/2);
color: red;
// 重要 -- 动画延时
&::before,
&::after {
animation-delay: -@ani-duration / @ballNum * 6 * @i;
}
}
// 类似于JavaScript中的递归
.loop(@i + 1);
}
// 先调用一次
.loop(1);
- .loop 可以理解为一个函数名,这个名称是任意的
- @i 是传递进去的参数
- when 类似于 JavaScript 中的 if 判断关键字
- when (@i <=@ballNum) 括号里面的是判断条件,可以理解为 if (i <= ballNum) { // 执行具体事件 } 这样子的判断执行语句
- @ballNum 此处的值为36,判断边界
-
动画
animation-name: moveBlack;
// 指定要绑定到选择器的关键帧的名称
animation-duration: 2000ms;
// or
animation-duration: 2s;
// 动画指定需要多少秒或毫秒完成
animation-timing-function:linear;
animation-timing-function使用的数学函数,称为三次贝塞尔曲线,速度曲线。使用此函数,您可以使用您自己的值,或使用预先定义的值之一:
值 | 描述 |
---|
linear | 动画从头到尾的速度是相同的。 |
ease | 默认。动画以低速开始,然后加快,在结束前变慢。 |
ease-in | 动画以低速开始。 |
ease-out | 动画以低速结束。 |
ease-in-out | 动画以低速开始和结束。 |
steps(int,start|end) | 指定了时间函数中的间隔数量(步长)。有两个参数,第一个参数指定函数的间隔数,该参数是一个正整数(大于 0)。 第二个参数是可选的,表示动画是从时间段的开头连续还是末尾连续。含义分别如下:start:表示直接开始。 end:默认值,表示戛然而止。 |
cubic-bezier(n,n,n,n) | 在 cubic-bezier 函数中自己的值。可能的值是从 0 到 1 的数值。 |
animation-delay: 6s
animation-iteration-count:3;
animation-iteration-count属性定义动画应该播放多少次。
值 | 描述 |
---|
n | 一个数字,定义应该播放多少次动画 |
infinite | 指定动画应该播放无限次(永远) |
-
@keyframes
要创建 CSS 动画,您首先需要了解 @keyframes 规则,@keyframes 规则用来定义动画各个阶段的属性值,类似于 flash 动画中的关键帧,语法格式如下:
@keyframes animationName {
from {
width: 100px;
}
to {
width: 200px;
// 里面可以设置任意的样式
}
}
// 或者
@keyframes animationName {
0% {
width: 100px;
}
50% {
width: 200px;
}
// 中间还可以添加其他百分比点位进行设置
100% {
width: 300px;
// 里面可以设置任意的样式
}
}
语法说明如下:
- animationName:表示动画的名称;
- from:定义动画的开头,相当于 0%;
- to:定义动画的结尾,相当于 100%;
最后说明一下,这份笔记并不全面,仅仅是对这个loading效果所用到的一些属性做了一些记录,如果还想深入了解,可以再查查资料进行系统的了解学习。
文中如果讲的有问题的地方还请评论区多多指教。
最后再说一句,如果对三维感觉很迷茫,不如多看看下面这两张图,然后对照代码多多思考。
正常情况
换个角度再看看
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)