一、簡介
Loading幾乎是每個應用都會用到的一個元件。很多元件庫都會提供相應的Loading元件,但是有的時候我們可能需要自定義Loading效果,掌握Loading元件製作的基礎知識將變得非常必要。Loading主要就是一個旋轉的圓環,而旋轉部分則比較簡單,直接通過CSS動畫即可實現,所以關鍵部分就是得到Loading的圓環。
二、通過border-radius繪製圓環
我們通常讓一個元素變成圓形是先將一個元素設定為長和寬相等的正方形,然後給這個元素設定一個border-radius值為50%。需要注意的是,border-radius: 50%是讓整個正方形元素都變成圓形,即包括邊框和內容區。所以我們可以通過控制元素邊框和內容區的大小,將元素的內容區域作為內圓,將元素的邊框區域作為外圓,從而繪製出一個圓環。
<div class="loading-css"></div>
.loading-css {
width: 50px; /*先將loading區域變成正方形*/
height: 50px;
display: inline-block; /*將loading區域變成行內元素,防止旋轉的時候,100%寬度都在旋轉*/
border: 3px solid #f3f3f3; /*設定四周邊框大小,並將顏色設定為淺白色*/
border-top: 3px solid red; /*將上邊框顏色設定為紅色高亮,以便旋轉的時候能夠看到旋轉的效果*/
border-radius: 50%; /*將邊框和內容區域都變成圓形*/
}
此時效果如下:
圓環效果已經出來了,接下來讓圓環旋轉起來即可,如:
@keyframes loading-360 {
0% {
transform: rotate(0deg); /*動畫起始的時候旋轉了0度*/
}
100% {
transform: rotate(360deg); /*動畫結束的時候旋轉了360度*/
}
}
.loading-css { /*在之前的CSS中加上動畫效果即可*/
animation: loading-360 0.8s infinite linear; /*給圓環新增旋轉360度的動畫,並且是無限次*/
}
二、通過svg來繪製圓環
SVG 意為可縮放向量圖形(Scalable Vector Graphics),其使用 XML 格式定義影像,<circle> 標籤可用來建立一個圓,同時外面必須巢狀一個<svg>標籤。
<svg viewBox="0 0 50 50" class="loading-svg">
<circle cx="25" cy="25" r="20" fill="none" class="path"></circle>
</svg>
.loading-svg {
width: 50px; /*設定svg顯示區域大小*/
height: 50px;
}
<svg>標籤的width和height設定的是svg圖形可顯示區域大小。而viewBox表示的是擷取圖形的區域,因為向量圖的繪製區域可以是無限大的,具體繪製在哪裡根據具體的設定而定,比如上面的circle就繪製在圓心座標為(25,25),半徑為20的圓形區域中,而viewBox設定為0 0 50 50,表示截圖區域為左上角座標為(0, 0),右下角座標為(50,50)的矩形區域內,即會擷取這個區域內的向量圖,然後將擷取的向量圖放到svg的可顯示區域內,同時會根據svg可顯示區域的大小等比例進行縮放,但是擷取的圖片必須在svg可顯示區域內完整顯示。
假如,現在講svg的大小設定為60px,如:
.loading-svg {
width: 60px; /*設定svg顯示區域大小*/
height: 60px;
}
如上分析,viewBox截圖區域中,繪製的圓的圓心正好在截圖區域的中心,所以截圖區域四周邊框與繪製的圓之間有5px的距離,而圓的半徑為20px,所以比例為1:4,現在將svg顯示區域變為60px,所以也需要將截圖區域等比例放大並佔滿整個svg顯示區域,截圖區域經過拉伸後,圓心位置變為了(30,30),即半徑變為了30,按1:4比例,半徑變為24,外圍變為了6,所以整個圓也會跟著變大。
需要注意的時候,<cicle>繪製的圓目前是看不到的,因為沒有給畫筆設定上顏色,如:
.path {
stroke: #409eff; /*給畫筆設定一個顏色*/
stroke-width: 2; /*設定線條的寬度*/
}
此時可以看到繪製出的圓環了。為了給圓環新增轉動效果,我們需要繪製帶缺口的圓環,後面通過改變缺口的位置大小來實現轉動效果,如:
.path {
stroke-dasharray: 95, 126; /*設定實現長95,虛線長126*/
stroke-dashoffset: 0; /*設定虛線的偏移位置*/
}
如圖所示,圓環的繪製起點是在水平方向最右邊的那個點,然後進行順時針繪製。因為該圓環的周長為23.1420=125.6,約等於126,stroke-dasharray設定了實線(可見部分)長為95,約等於圓的3/4,所以只能繪製到圓環的最高點位置,接下來是126的虛線,但是圓環周長只有126,所以只能顯示31的虛線。可以看做是一根無限迴圈的水平線條,實線(-221,0)---虛線(-126,0)---目前起點為(0,0)---實線(95,0)---虛線(221,0)---實線(316,0),然後讓水平線的起點(0,0)位置與圓環的起點位置重合,水平線順時針沿著圓環繞即可,隨著stroke-dashoffset起點位置的偏移,左側的(-126,0)的虛線就可以慢慢顯示出來。當stroke-dashoffset值為負數的時候,上面的線往右拉,當stroke-dashoffset值為正數的時候,下面的線往右拉。
接下來就是新增圓環的轉動效果,分別設定三個動畫狀態,如:
// 0%
{
stroke-dasharray: 1, 126; /*實線部分1,虛線部分126*/
stroke-dashoffset: 0; /*前面1/126顯示實線,後面125顯示空白*/
}
從圓環最右邊作為起點繪製1個畫素的距離的實線,接下來繪製126畫素的虛線(空白),因為圓周長為126,所以剩餘部分全部為空白,如圖所示,
// 50%
{
stroke-dasharray: 95, 126; /*實線部分95,虛線部分126*/
stroke-dashoffset: -31px; /*順時針偏移31/126,即前31/126顯示空白,後面3/4顯示線條*/
}
從圓環的最右邊作為起點,並且順時針移動31畫素,即圓環的1/4,所以實線起點變為了圓環的最底部,實線長度為95畫素,即圓環的3/4,如圖所示,
// 100%
{
stroke-dasharray: 6, 120; /*實線部分6,虛線部分120*/
stroke-dashoffset: -120px; /*最後順時針偏移120/126,即前120/126顯示空白,後面6點顯示線條部分*/
}
從圓環的最右邊作為起點,並且順時針移動120畫素,所以實線長度僅剩下6畫素了,如圖所示,
給圓環加上動畫效果,如:
.path {
animation: loading-dash 1.5s ease-in-out infinite;
}
@keyframes loading-dash {
0% {
stroke-dasharray: 1, 126; /*實線部分1,虛線部分126*/
stroke-dashoffset: 0; /*前面1/126顯示實線,後面125顯示空白*/
}
50% {
stroke-dasharray: 95, 126; /*實線部分95,虛線部分126*/
stroke-dashoffset: -31px /*順時針偏移31/126,即前31/126顯示空白,後面3/4顯示線條*/
}
to {
stroke-dasharray: 6, 120; /*實線部分6,虛線部分120*/
stroke-dashoffset: -120px; /*最後順時針偏移120/126,即前120/126顯示空白,後面6點顯示線條部分*/
}
}
為了讓Loading動畫更加生動細膩,我們還可以給svg標籤也加上一個旋轉動畫,如:
.loading-svg {
width: 50px; /*設定svg顯示區域大小*/
height: 50px;
animation: loading-rotate 1.5s infinite ease-in-out; /*給svg也加上一個旋轉動畫*/
}
@keyframes loading-rotate {
to {
transform: rotate(1turn); // 旋轉1圈
}
}
三、通過iconfont字型圖示
我們可以直接通過iconfont字型圖示代替圓環的繪製,直接以字型的形式顯示出圓環,然後給其加上旋轉動畫即可,如:
我們可以在iconfont網站上下載喜歡的Loading圖案。字型圖示下載後,將解壓後的內容拷貝到專案中,並引入其中的iconfont.css到頁面中,給要顯示字型圖示的元素加上iconfont類樣式,字型圖示會有一個對應的unicode編碼,通過::before設定content為該unicode編碼即可顯示對應的字型圖示了,或者直接在unicode碼前加上\&#x,並作為元素內容。
<link rel="stylesheet" href="icon/iconfont.css">
<style>
.icon-loading {
display: inline-block; /*需要設定為行內塊元素動畫才會生效*/
font-size: 56px;
color: grey;
}
.icon-loading::before {
content: "\e65b"; /*顯示字型圖內容,值為\unicode*/
}
</style>
<i class="icon-loading iconfont"></i>
<!--或者-->
<i class="iconfont"></i><!--值為&#xunicode-->
接下來讓字型圖示旋轉起來即可,如:
.icon-loading {
animation: rotating 2s infinite linear;
}
@keyframes rotating {
0% {
transform: rotate(0deg) /*動畫起始位置為旋轉0度*/
}
to {
transform: rotate(1turn) /*動畫結束位置為旋轉1圈*/
}
}