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這篇文章整理而來,有刪減,有疏漏或者理解不到位的地方,還請多多指教!