【前端入門系列】HTML5動畫與動效(之五)

我猜,80%的前端在面對loading效果的時候,都會使用現成的loading代碼或圖片。其實自己動手做做這些小東西也是挺有意思的,至少能夠讓自己對CSS3和animation動畫等方面有更加深入的了解。

大家好,最近幾個月工作較忙,有好一陣子沒有更新這個系列了。想想不能讓這個系列無疾而終,今天就接著再來一篇吧。

HTML5動畫與動效的基礎(JS動畫除外),如transition動畫、animation動畫、逐幀動畫等,在前幾篇文章中已經基本介紹過了。但是,光是了解基礎代碼,90%的初學者在最初的實踐中具體使用時還是會感到懵逼和無所適從的。就像我們學數學,有時候遇到實踐性較強的應用題,都不知道該怎麼用學習的各種公式和定理去解題一樣。因此,最近這幾篇文章,我想主要圍繞HTML5動畫與動效的實際應用來進行演示,通過實操讓大家更加深入地了解相關的基礎知識,幫助大家在實踐中更好地落地運用。

在上一篇文章中我們運用了transition動畫來形成頁面切換效果,在本文中,我們將同樣對另一種CSS3動畫——animation動畫加以深入挖掘。在此我們將著重展示幾個載入(loading)動畫案例,通過這些案例的製作,或許你能夠初步感受到animation動畫的「強大」。

本系列主要針對前端入門的初學者,前端老司機可繞路。

基礎HTML代碼

Loading元素是頁面中較為常見的一種元素,它能夠非常有效地消除用戶等待載入的焦慮感,一般而言此類元素都需要帶有一些動態效果,表示頁面正在「拚命」、「飛速」載入中。

現在,我們就要開始做一個最簡單的Loading元素啦。

loading元素的HTML代碼如下:

<div class="loader">Loading...</div>n

我們的目標是要製作一個不停旋轉的半圓圈,以作為頁面的loading效果,如下圖所示。

先畫一個圈

首先,讓我們先畫出整個圓圈,思路很簡單,我們用50%的border-radius形成圓形效果,代碼如下:

.loader {nttext-indent: -9999em; /*隱藏文字*/ntposition: relative;ntwidth: 200px;ntheight: 200px;ntbox-shadow: inset 0 0 0 15px #FFF; /*設置內部陰影,顏色為白色,寬度為15像素*/ntborder-radius: 50%; /*使形狀輪廓為圓形*/n}n

在以上代碼中,我們使用了box-shadow而非border屬性來生成圓圈效果,這是由於box-shadow將不會影響div內部元素的定位,而帶有一定寬度的border則有可能會引起內部元素位置的推移。圓圈效果如下圖所示。

把一個圈變成半個圈

事實上,我們只需要以上的圓圈的一半區域,那如何能夠裁去半邊圓圈呢?在此我們要使用一種障眼法。為div創建一個before偽元素,代碼如下:

.loader::before {ntposition: absolute;ntcontent: ;ntwidth: 100px;ntheight: 200px;ntbackground: #FF7B33;ntleft: 100px;n}n

在以上代碼中,我們使偽元素的寬度為100像素,高度為200像素,並距離左側100像素,為了使大家能清楚地辨析該形狀區域,我們在此使用了紅色(#FF7B33)作為背景色,如下圖所示。

接下來,要使得這一形狀從矩形變為半圓形,只需對其border-radius屬性加以設置即可,代碼如下:

.loader::before {nt/*其餘代碼*/ntborder-radius: 0 200px 200px 0; /*設置頂部和左側圓角為0像素,其餘兩側為200像素*/n}n

在以上代碼中,我們巧妙地運用了不同邊的圓角弧度來生成了半圓形狀,如下圖所示。

接下來,只需要將半圓的背景色修改為和網頁的背景色(在此為#4EA980)相同即可,代碼如下:

.loader::before {ntbackground: #4EA980; /*設置背景色與網頁背景色相同*/n}n

通過以上的「障眼法」,我們就順利地得到了一個半圓圈形狀,如下圖所示。

軌跡線的製作

我們還要創造一個更淺的透明白色圓圈,以作為半圓圈形狀的軌跡背景,代碼如下:

.loader::after {ntposition: absolute;ntcontent: ;ntwidth: 200px;ntheight: 200px;ntborder-radius: 50%;ntleft: 0;ntbox-shadow: inset 0 0 0 15px rgba(255,255,255,.2); /*設置內部陰影為15像素寬,顏色為20%透明度的白色*/n}n

在以上代碼中,我們仍然使用了box-shadow來繪製該軌跡背景,由於after偽元素默認的顯示層級高於before偽元素,因此它不會被半圓形狀所遮住,其顯示效果如下圖所示。

讓圓圈轉起來

請注意,接下來就是動畫的製作時間!!

我們仍然先定義好關鍵幀動畫,代碼如下:

@-webkit-keyframes load-effect {nt0% {ntt-webkit-transform: rotate(0deg);ntttransform: rotate(0deg);nt}nt100% {ntt-webkit-transform: rotate(360deg);ntttransform: rotate(360deg);nt}n}n@keyframes load-effect {nt0% {ntt-webkit-transform: rotate(0deg);ntttransform: rotate(0deg);nt}nt100% {ntt-webkit-transform: rotate(360deg);ntttransform: rotate(360deg);nt}n}n

在load-effect動畫中,我們使得元素從最初的0度旋轉到360度。值得注意的是,在之前的animation中,我們使用了from和to作為關鍵幀動畫的首尾兩個節點,而在本動畫中,我們使用了更加靈活的百分比作為節點,其中0%代表動畫開始,100%代表動畫結束。

接下來,我們將旋轉半圓,通過綠色半圓對下方白色圓圈的遮罩,形成轉圈效果。設置before偽元素的animation屬性來生成動畫,代碼如下:

.loader::before {nt-webkit-animation: load-effect 2s infinite;ntanimation: load-effect 2s infinite;n}n

測試頁面,現在我們看到的效果將出現一點小問題,before偽元素似乎並沒有圍繞圓圈的中心旋轉,而是圍繞半圓自己的中心轉圈了,我們將半圓的背景色調回紅色來看看這一問題,如下圖所示。

要解決這一問題,則需要我們手動設置半圓的旋轉中心,使其位於左側垂直居中的位置,代碼如下:

.loader::before {nt-webkit-transform-origin: 0px 100px;nttransform-origin: 0px 100px;n}n

以上代碼使用了transform-origin屬性來完成了旋轉中心的設置。測試頁面,新的半圓旋轉效果如圖所示。

最後,將半圓的顏色改回背景色,我們將得到最終的loading動畫效果,如圖所示。

升級版:給loading元素加個尾巴

另一種常見的loading效果是帶有漸變「尾巴」的轉圈效果,我們將接下來製作這一效果。其中,漸變「尾巴」可以使用linear-gradient來繪製,代碼如下:

.loader {nttext-indent: -9999em;ntposition: relative;ntwidth: 200px;ntheight: 200px;ntbackground: #ffffff;ntbackground: -webkit-linear-gradient(left, #ffffff 10%, rgba(255, 255, 255, 0) 50%);ntbackground: linear-gradient(to right, #ffffff 10%, rgba(255, 255, 255, 0) 50%);ntborder-radius: 50%;ntbox-shadow:inset 0 0 0 20px rgba(255,255,255,.2);n}n

在以上代碼中,設置linear-gradient的方向為從左到右,從最左側向右10%均為純白色,再向右到50%的位置漸變為完全透明的白色,透明白色軌跡則使用box-shadow來製作,顯示效果如圖所示。

運用之前繪製半圓的經驗,我們也可以使用before偽元素來繪製四分之一個圓,將其放在圓圈的左上角,這部分將作為圓圈的實體區域,代碼如下:

.loader::before {ntposition: absolute;ntcontent: ;ntwidth: 50%;ntheight: 50%;ntbackground: #FFF;ntborder-radius: 100% 0 0 0;ntleft:0;nttop:0;n}n

測試頁面,目前的載入效果如圖所示。

然後,我們再添加after偽元素,繪製一個內部的圓圈,使其顏色與背景色相同即可,代碼如下:

.loader::after {ntbackground: #4ea980;ntwidth: 160px;ntheight: 160px;ntborder-radius: 50%;ntcontent: ;ntposition: absolute;nttop: 20px;ntleft: 20px;n}n

由於大圓圈的直徑為200像素,軌跡寬度為20像素,因此中央的小圓圈的寬度為160像素,並距離頂部和底部20像素,這樣正好能夠將中央區域遮住,如圖所示。

最後,我們使整個loader元素旋轉即可,代碼如下:

.loader {nt-webkit-animation: load-effect 2s infinite linear;ntanimation: load-effect 2s infinite linear;n}n

測試頁面,現在我們就得到了流行的「拖尾」圓圈載入效果,如圖所示。

強化升級版:三點狀loading元素

以上的animation動畫都較為簡單,只設置了第一幀和最後一幀。在接下來的兩種loading效果中,我們將嘗試更為複雜的animation關鍵幀設置。

我們先來看看以下一段樣式代碼:

.loader {ntfont-size: 20px;ntwidth: 1em;ntheight: 1em;ntborder-radius: 50%;ntposition: relative;nttext-indent: -9999em;ntbox-shadow: -3em 2em 0 .5em #FFF, 0 2em 0 .5em #FFF, 3em 2em 0 .5em #FFF;n}n

在以上代碼中,除最後一行外,其餘都是我們所熟知的樣式代碼,它們設置了loader的寬度和高度,以及圓角弧度,並隱藏loader中的文字。然而,測試頁面,我們卻得到了並排的三個白點,如圖所示。

為什麼最後一行的box-shadow會生成三個白色圓點呢?當我們為loader添加紅色背景後便可一目了然,如圖9.82所示。實際上,三個白點是通過box-shadow生成的三個「陰影」,其顏色為白色,且由於loader自身為圓形,因此陰影也就顯示為了白色圓點。三個圓點的排列是由第1、2兩個參數指定的,如「-3em

2em」表示最左側的圓點水平左移三個字元的距離,並向下移動兩個字元距離。第三個參數為0,表示圓點沒有模糊效果。圓點的大小則是由第4個參數控制的,默認的陰影大小是與loader實體大小一致的,而設置為0.5em則表示將陰影外擴二分之一字元寬度,因此白點的直徑將是紅色圓點(loader本體)的一倍。

如果我們將第二個圓點的擴展參數改為0,第三個圓點改為-0.5em,則表示將第二個圓點恢復到與loader同樣大小,並將第三個圓點縮小直至消失,代碼如下:

.loader {ntbox-shadow: -3em 2em 0 .5em #FFF, 0 2em 0 0 #FFF, 3em 2em 0 -.5em #FFF;n}n

以上代碼將生成如下的圓點效果,如圖所示。

利用以上的box-shadow特性,我們就能夠製作出一種流行的loading效果,即三個並排的點依次放大和縮小,代碼如下:

.loader {nt-webkit-animation: load-effect 1s infinite linear;ntanimation: load-effect 1s infinite linear;n}n@-webkit-keyframes load-effect {nt/*代碼略,與下同*/n}n@keyframes load-effect {nt0% {nttbox-shadow: -3em 2em 0 .5em #FFF, 0 2em 0 0 #FFF, 3em 2em 0 -.5em #FFF;nt}nt25% {nttbox-shadow: -3em 2em 0 0 #FFF, 0 2em 0 -.5em #FFF, 3em 2em 0 0 #FFF;nt}nt50% {nttbox-shadow: -3em 2em 0 -0.5em #FFF, 0 2em 0 0 #FFF, 3em 2em 0 .5em #FFF;nt}nt75% {nttbox-shadow: -3em 2em 0 0 #FFF, 0 2em 0 .5em #FFF, 3em 2em 0 0 #FFF;nt}nt100% {nttbox-shadow: -3em 2em 0 .5em #FFF, 0 2em 0 0 #FFF, 3em 2em 0 -.5em #FFF;nt}n}n

在以上的幀動畫中,我們分別定義了0%、25%、50%、75%和100%五種動畫狀態,使三個點依次從大到小,再從小到大變化,測試效果如圖所示。

在本例中使用了em作為相對度量單位,它的好處是便於修改大小,我們只需要調整基本的font-size屬性,就能夠從整體上改變動畫效果的寬度和高度。

以上動畫由於需要循環播放,因此0%和100%的動畫關鍵幀的狀態是一致的,我們可以將其用逗號分隔,合併為如下代碼形式:

@keyframes load-effect {nt0%,nt100% {nttbox-shadow: -3em 2em 0 .5em #FFF, 0 2em 0 0 #FFF, 3em 2em 0 -.5em #FFF;nt}nt/*其它關鍵幀*/n}n

超級強化升級版:環圈loading元素

在本文最後,我們將製作一個更為複雜的關鍵幀動畫,在這個動畫中繪製了8個白色圓點,分別位於loader元素上下左右,以及斜上斜下斜左斜右等8個方位。我們還為動畫設置了8個關鍵幀,分別使8個圓點依次放大和輸小,代碼如下:

@keyframes load-effect {nt0%,nt100% {nttbox-shadow: 0 -3em 0 .2em #FFF, 2em -2em 0 0 #FFF, 3em 0 0 -.5em #FFF, 2em 2em 0 -.5em #FFF, 0 3em 0 -.5em #FFF, -2em 2em 0 -.5em #FFF, -3em 0 0 -.5em #FFF, -2em -2em 0 0 #FFF;nt}nt12.5% {nttbox-shadow: 0 -3em 0 0 #FFF, 2em -2em 0 .2em #FFF, 3em 0 0 0 #FFF, 2em 2em 0 -.5em #FFF, 0 3em 0 -.5em #FFF, -2em 2em 0 -.5em #FFF, -3em 0 0 -.5em #FFF, -2em -2em 0 -.5em #FFF;nt}nt25% {nttbox-shadow: 0 -3em 0 -.5em #FFF, 2em -2em 0 0 #FFF, 3em 0 0 .2em #FFF, 2em 2em 0 0 #FFF, 0 3em 0 -.5em #FFF, -2em 2em 0 -.5em #FFF, -3em 0 0 -.5em #FFF, -2em -2em 0 -.5em #FFF;nt}nt37.5% {nttbox-shadow: 0 -3em 0 -.5em #FFF, 2em -2em 0 -.5em #FFF, 3em 0 0 0 #FFF, 2em 2em 0 .2em #FFF, 0 3em 0 0 #FFF, -2em 2em 0 -.5em #FFF, -3em 0 0 -.5em #FFF, -2em -2em 0 -.5em #FFF;nt}nt50% {nttbox-shadow: 0 -3em 0 -.5em #FFF, 2em -2em 0 -.5em #FFF, 3em 0 0 -.5em #FFF, 2em 2em 0 0 #FFF, 0 3em 0 .2em #FFF, -2em 2em 0 0 #FFF, -3em 0 0 -.5em #FFF, -2em -2em 0 -.5em #FFF;nt}nt62.5% {nttbox-shadow: 0 -3em 0 -.5em #FFF, 2em -2em 0 -.5em #FFF, 3em 0 0 -.5em #FFF, 2em 2em 0 -.5em #FFF, 0 3em 0 0 #FFF, -2em 2em 0 .2em #FFF, -3em 0 0 0 #FFF, -2em -2em 0 -.5em #FFF;nt}nt75% {nttbox-shadow: 0 -3em 0 -.5em #FFF, 2em -2em 0 -.5em #FFF, 3em 0 0 -.5em #FFF, 2em 2em 0 -.5em #FFF, 0 3em 0 -.5em #FFF, -2em 2em 0 0 #FFF, -3em 0 0 .2em #FFF, -2em -2em 0 0 #FFF;nt}nt87.5% {nttbox-shadow: 0 -3em 0 0 #FFF, 2em -2em 0 -.5em #FFF, 3em 0 0 -.5em #FFF, 2em 2em 0 -.5em #FFF, 0 3em 0 -.5em #FFF, -2em 2em 0 0 #FFF, -3em 0 0 0 #FFF, -2em -2em 0 .2em #FFF;nt}n}n

實際上,以上代碼的原理和前一個元素是基本相同的,只是點的數量更多了,位置參數更多了。在做這種複雜的動畫時,你完全可以使用一些其他的工具來幫助你(包括計算器)。

測試頁面,以上動畫的顯示效果如圖所示。

小結

到現在為止,相信大家對animation動畫的使用又有了更深入的體會。如果你連上面這些複雜的loading元素都能做出來,那我相信其他的動畫也基本不在話下了!

最後,送各位學習者一句話:實踐出真知。希望大家能夠一起進步!

THE END!

廣告:

個人新書 《HTML5基礎知識、核心技術與前沿案例》,噹噹、京東、亞馬遜有售。

噹噹:《HTML5基礎知識 核心技術與前沿案例》(劉歡)

京東:《HTML5基礎知識 核心技術與前沿案例》(劉歡)


推薦閱讀:

什麼是M站?
[一勺燴]最流行前端開發圖表顯示組件總結
如何免費製作一個H5微場景?
【前端入門系列】HTML5動畫與動效(之四)

TAG:HTML5 | 前端入门 | 动画 |