CSS 动画实战:创建一个漂亮的加载动画

这篇文章,用一个实例来讲下用伪元素和CSS Animation来创建一个漂亮的加载动画。

首先来看下,要实现的动画效果:

先来分析下,这个动画效果是由哪几个动画组成:

1、线段依次出现。

2、然后红色、橙色和白色矩形依次出现。

3、这些矩形出现之后,然后消失。

4、线段消失。

这里我们只需要实现1和2动画效果。后面的3和4,只需要在1和2的基础上使用animation-direction: alternate;这个属性就可以实现了,这个属性会倒着播放动画效果。然后使用animation-iteration-count: infinite;是动画循环来播放就实现了我们要实现的动画效果。

先来写基本的HTML结构:

   
     <!-- <link rel="preload"> for CSS, JS, and font files  -->
     < style type = "text/css" data-filtered = "filtered" >
       /*
        *  All the CSS for the loader
        *  Minified and vendor prefixed
        */
     </ style >
   
   
     < div class = "loader" >
       <!-- HTML for the loader -->
     </ div >
     < header >
     < main >
     < footer >
     <!-- Tags for CSS and JS files -->
   
 
</ footer ></ main ></ header >

CSS放在顶部,这样可以让图像能最快的渲染出来,呈现给用户。

实现静态的Logo

接下来我们一步一步来实现这个动画效果。第一步就是先来实现这个加载效果的静态UI。

div.logo这个div作为父级元素用来包裹三个矩形,矩形分别用它们所属的颜色来命名类名:

< div class = "logo" >
   < div class = "white" ></ div >
   < div class = "orange" ></ div >
   < div class = "red" ></ div >
</ div >

这里我们使用绝对定位来实现矩形位置的摆放。

使用SCSS来实现这个布局:

div.logo {
   width : 100px ;
   height : 100px ;
   border : 4px solid black ;
   box-sizing: border-box;
   position : relative ;
   background-color : white ;
   & > div {
     position : absolute ;
   }
   div. red {
     border-right : 4px solid black ;
     top : 0 ;
     bottom : 0 ;
     left : 0 ;
     width : 27% ;
     background-color : #EA5664 ;
   }
   /* 其它的矩形样式也差不多 */
}

最后就实现了这个Logo静态UI:

demo地址

线段动画

跟上步骤,先来实现线段的动画效果。

CSS现在还不能直接对边线(border)做动画效果。所以,需要找一个其它的方法来实现这个边线动画效果。

我们可以换种方式,比如我们可以把这个边线分成四条线段,使它们依次出现从而实现边线的动画效果。我们将使用两个伪元素来实现这个效果。

通过伪元素实现边线后,可以通过改变它们的高度(height)属性及葱0%到100%来实现动画效果。

我们先来用伪元素实现动画效果。div.logo::before定位在div.logo左上的位置,来实现顶部和右边的边线。div.logo::after用来实现底部和左边的边线。

下面是SCSS的代码:

div.logo {
   width: 100px;
   height: 100px;
   box-sizing: border-box;
   position: relative;
   background-color: white;
   &::before,
   &::after {
     z-index: 1;
     box-sizing: border-box;
     content: '';
     position: absolute;
     border: 4px solid transparent;
     width: 100%;
     height: 100%;
   }
   &::before {
     top: 0;
     left: 0;
     border-top-color: black;
     border-right-color: black;
   }
   &::after {
     bottom: 0;
     right: 0;
     border-bottom-color: red; // Red for demo purposes only
     border-left-color: red;
   }
}

通过改造,使用伪元素实现了边框的效果:

demo地址

先来创建第一个边线动画效果。

当然,在初始状态的时候,先要把边线的width和height都设置为0。然后使用关键帧分别把width和height设置为100%。

在改变width和height的时候,同时把颜色从透明改为黑色,这样边线的动画效果就实现了。

下面是代码:

div.logo {
   &::before,
   &::after {
     /* ... */
     width : 0 ;
     height : 0 ;
     animation-timing-function: linear;
   }
&::before {
     /* ... */
     animation: border-before 1.5 s infinite;
     animation- direction : alternate;
   }
}
@keyframes border-before {
   0% {
     width : 0 ;
     height : 0 ;
     border-top-color : black ;
     border-right-color : transparent ;
   }
   24.99% {
     border-right-color : transparent ;
   }
   25% {
     height : 0 ;
     width : 100% ;
     border-top-color : black ;
     border-right-color : black ;
   }
   50% ,
   100% {
     width : 100% ;
     height : 100% ;
     border-top-color : black ;
     border-right-color : black ;
   }
}

依样画葫芦,重复这个步骤来实现另外边线的动画效果。效果如下:

demo地址

矩形动画

下面来实现矩形的动画效果。

要实现这个效果一个主要的挑战是每个动画效果的关键帧之间的衔接。我们需要合理的安排每一个关键帧动画出现的时机,从而完整的把整个动画效果衔接起来。

对于边线动画,每一个边线动画将花费25%的时间来呈现。边线动画完成后,然后再来呈现矩形的动画。这过程中,要花点时间去尝试,经过尝试,我们选择整个的动画时间是1.5秒,具体的动画所占时间比如下所示:

1、 25%的关键帧:顶部和右边的边线动画占的时间比。

2、25%到50%:关键帧是底部和左边的边线动画的时间。

3、50到65%:关键帧是红色矩形的动画。

4、65到80%:关键帧是橙色矩形的动画。

5、75到90%:关键帧是白色矩形的动画。

根据上面安排的时间,现在就可以来实现接下来的矩形动画了,通过改变矩形的透明度和宽度来实现:

div.logo {
   div. red {
     /* ... */
     width : 0 ;
     animation: red 1.5 s infinite;
     animation- direction : alternate;
   }
}
@keyframes red {
   0% ,
   50% {
     width : 0 ;
     opacity: 0 ;
   }
   50.01% {
     opacity: 1 ;
   }
   65% ,
   100% {
     opacity: 1 ;
     width : 27% ;
   }
}

其它矩形的动画通过同样的方式来实现,最后一个帅气漂亮的加载动画就实现了:

demo地址

OK,一个简单帅气漂亮的加载动画就完成了。

本文主要是从How to create a beautiful animated loader with nothing but CSS这篇文章整理而来,有删减,有疏漏或者理解不到位的地方,还请多多指教!