CSS animation 实现 4 圆点跳动 loading
开篇
CSS3 animation
动画可以实现很多功能,比如项目中常用到的 loading
效果。
最近项目中涉及到一个 loading 交互:“四个小圆点依次跳动”。最初采用 UI 涉及的 gif
动图来呈现加载效果,但由于动图的体积太大,最终改用 CSS3 animation 来实现。最终效果展示如下:
分析
从效果图中可以看出,圆点跳动的交互有两个:上移 和 放大,在 CSS3 中 transform translateY/scale
可以轻松实现。
接下来为了让其动起来,需要通过定义 animation
动画来完成。
我们先来回顾 animation 常用属性:
- animation-name && @keyframes
@keyframes
用于定义一个动画,animation-name
是设置当前元素要使用的动画。在定义动画时,from/to 或者 百分比进度
都可以定义动画每个阶段呈现的效果:
@keyframes example {
from {background-color: red;}
to {background-color: yellow;}
}
// or
@keyframes example {
0% {background-color: red;}
25% {background-color: yellow;}
50% {background-color: blue;}
100% {background-color: green;}
}
div{
animation-name: example;
animation-duration: 4s;
}
- animation-duration
指定动画需要多少秒或毫秒完成。
animation-duration: 4s;
- animation-timing-function
指定动画将如何完成一个周期,可选值有:
- linear,动画从头到尾的速度是相同的;
- ease,默认。动画以低速开始,然后加快,在结束前变慢。
- ease-in,动画以低速开始。
- ease-out,动画以低速结束。
- ease-in-out,动画以低速开始和结束。
animation-timing-function:linear;
- animation-delay
用于延迟动画的执行时间。
animation-delay: 2s;
- animation-iteration-count
定义动画的播放次数。可以设定数字来确认播放次数,当设置 infinite
时表示无限次播放。
animation-iteration-count: infinite;
- animation-direction
指定是否应该轮流反向播放动画。可选值有:
- normal,默认值。动画按正常播放。
- reverse,动画反向播放。
- alternate,动画在奇数次(1、3、5...)正向播放,在偶数次(2、4、6...)反向播放。
- alternate-reverse,动画在奇数次(1、3、5...)反向播放,在偶数次(2、4、6...)正向播放。
要实现 loading 跳动动画,使用到的动画属性如下:
- animation-name,指定动画名称
- animation-duration,指定动画完成一轮所用的时间
- animation-delay,指定动画延迟执行时间
- animation-iteration-count,指定动画播放次数,我们使用
infinite
无限次播放
下面我们来看看完整代码实现:
完整代码
- 首先是 DOM 节点,我们只需一个容器 和 四个小圆点元素即可:
<div class="box">
<span></span>
<span></span>
<span></span>
<span></span>
</div>
- css 样式,借助
animation
来实现,
- 每个圆点的动画执行时机不同,这里使用
animation-delay
做延迟执行: - 由于产品设计上第四个圆点的跳动交互与前三个不同,所以单独设定
loading-beat-last
。
<style>
*{
padding: 0;
bottom: 0;
}
.box{
width: 100px;
height: 50px;
margin: 100px auto;
display: flex;
align-items: center;
justify-content: center;
}
span{
display: inline-block;
width: 10px;
height: 10px;
border-radius: 50%;
margin-right: 5px;
animation-name: loading-beat;
/* 动画完成一个周期所需要的时间 */
animation-duration: 1.2s;
/* 定义动画从何时开始(延迟) */
animation-delay: 0s;
/* 动画播放次数(无限) */
animation-iteration-count: infinite;
}
span:nth-child(1){
background: #E6804A;
}
span:nth-child(2){
background: #FFD14E;
animation-delay: .2s;
}
span:nth-child(3){
background: #54BFFF;
animation-delay: .4s;
}
span:nth-child(4){
background: #59D8AB;
animation-delay: .6s;
animation-name: loading-beat-last;
}
@keyframes loading-beat {
0%{
transform: translateY(0) scale(1);
}
25% {
transform: translateY(-8px) scale(1.5);
}
50%, 75%, 100% {
transform: translateY(0px) scale(1);
}
}
@keyframes loading-beat-last {
0%{
transform: translateY(0) scale(1);
}
25%, 50% {
transform: translateY(-8px) scale(1.5);
}
60% {
transform: translateY(0px) scale(1);
}
}
</style>
转载自:https://juejin.cn/post/7241125859728851000