利用border-radius屬性及動畫屬性制作圓餅loading動畫

百度前端技術學院2017于2月24日開始進行,一共有6個學院可供學習,分別是小薇學院(html/css基礎)、斌斌學院(js基礎)、耀耀學院(小游戲/交互)、商業平臺學院(web/ios/android)、ECharts & WebVR學院(VR相關)和糯米學院(css3/vue等),從百度前端技術學院今年推出的各學院任務看來,目前互聯網行業對從事前端行業的程序員要求越發高了。轉行前端或是才開始學習前端的同學任重而道遠,大家一起加油,共勉。

《CSS3圓餅loading效果》作為糯米學院中的進階任務,目的主要是讓學員通過完成任務,掌握border-radius屬性的使用以及旋轉動畫的設置。在已經完成鼠標懸浮效果任務之后,相對來說本任務要簡單很多。以下是總結。

任務分解:該任務要達到的效果。如網頁中顯示情況,可將任務分解為兩個小任務:

1.制作四分之三圓環并旋轉;
2.制作圓餅,圓餅內有兩種顏色,分別交替旋轉擴大其扇形區域(從0deg到到360deg),以達到圓餅loading效果。

通過完成任務,使用到如下一些重要屬性:

1.制作圓環,使用偽元素,使用border(包括其transparent值);
2.制作圓餅過程中,使用到animation-timing-function屬性的steps()曲線;
3.圓餅及圓環的旋轉,使用animation系列屬性,并使用transform設置旋轉角度,使用transform-origin屬性設置旋轉中心。

以下是完成本任務后的html結構:

<header>
  <h1><a >小星的博客|Small Star's Blog</a></h1>
  <ul>
    <li><a href="#top-bottom1">點我</a></li>
    <li><a href="#top-bottom2">快點我</a></li>
      <li><a href="#top-bottom3">點我吧</a></li>
      <li><a href="#top-bottom4">點我啦</a></li>
  </ul>
</header>
<article>
  <p class="round1">
    <span class="bgcircle">
      <span class="left"><span class="spining"></span></span>
      <span class="right"><span class="spining"></span></span>
    </span>
  </p>
  <p class="round2">
    <span class="bgcircle">
      <span class="inner">
        <span class="spiner"></span>
        <span class="filler"></span>
        <span class="masker"></span>
      </span>
      <span class="inner2">
        <span class="spiner"></span>
        <span class="filler"></span>
        <span class="masker"></span>
      </span>
    </span>
  </p>
</article>
<footer>
  <p>版權所有 &copy 小星</p>
</footer>
</body>
</html>

其中,round1為使用第一種方法制作圓餅時的loading整體結構,round2為使用第二種方法制作圓餅時的loading整體結構。可以明顯發現round2方法結構復雜,實際上其實現方法也較round1方法笨拙。結構樣式代碼請見文末demo代碼地址。頁面圖如下:

頁面圖

圓環及圓餅制作原理如下:

1.四分之三圓環的旋轉:
  實現原理:首先將上文html結構中的類名為bgcircle的span元素設置為圓形(將其border-radius設置為50%即可),其寬高大于兩個子元素span,以便圓環與圓餅分開。在.bgcircle上設置偽元素,同樣設置為圓形,大小與.bgcircle相同,再設置偽元素邊框,其中任一邊框設置為transparent即可。最后利用animotion和transform設置旋轉動畫。css代碼如下:

/*2-1-1.制作大圓背景*/
.bgcircle{
  position:relative;
  display:inline-block;
  height:80px;
  width:80px;
  margin:50% 0 0 50%;
  top:-30px;
  left:-30px;
  border-radius:50%;
  overflow:hidden;
}
/*2-2.loading圓環*/
.bgcircle::before{
  content:"";
  position:absolute;
  width:100%;
  height:100%;
  box-sizing:border-box;
  border:4px solid #BD50A3;
  border-top:4px solid transparent;
  border-radius:50%;
  -webkit-animation:circle-spining 4s infinite linear;
  animation:circle-spining 4s infinite linear;
  -webkit-transform-origin:50% 50% 0;
  transform-origin:50% 50% 0;
}
@keyframes circle-spining{
  0%{transform:rotate(0deg);}
  50%{transform:rotate(-180deg);}
  100%{transform:rotate(-360deg);}
}
@-webkit-keyframes circle-spining{
  0%{-webkit-transform:rotate(0deg);}
  50%{-webkit-transform:rotate(-180deg);}
  100%{-webkit-transform:rotate(-360deg);}
}

2.圓餅旋轉:
  (1)方法一:主要參考codepen網站中Geoffrey CrofteCSS Loaderdemo,其中也寫了一些其他loading效果。總體來說,這些loading效果的主要原理都是:在.bgcircle之下,設置.left、.right為左右半圓,拼接為一個圓餅,對.left,設置其子元素.spining往右移至.right區域,并形成半圓與.right區域重疊,此時只有.spining旋轉至.left區域時才能顯示出來。同理,設置了.right的子元素.spining。最后,對兩個.spining子元素設置不同的旋轉動畫已達到要求效果。css代碼過長,請見文末demo代碼地址,其旋轉過程如下步驟表述:

a.初始狀態下,兩個.spining都沒有旋轉(圖中深紫色圓餅):此時.left.spining圍繞圓心開始逆時針旋轉,至-180deg:

b.“.left.spining”圍繞圓心開始逆時針旋轉,至-180deg(圖中淺紫色半圓):

c.“.left.spining”停止旋轉,“.right.spining”開始旋轉至-180deg,此時兩個.spining都顯示出來了,形成淺紫色圓餅:

d.“.right.spining”停止旋轉,“.left.spining”又開始旋轉,從-180deg旋轉至-360deg,此時只剩下“.right.spining”形成的淺紫色右半圓:

e.“.left.spining”一周的旋轉動畫結束,停止旋轉;“.right.spining”開始最后半周的旋轉,至-360deg停止。整個一周的動畫結束。對此動畫設置無限循環次數,即可達到最終效果。

(2)方法二:參考張鑫旭博客的文章CSS3實現雞蛋餅餅狀圖loading等待轉轉轉,在張鑫旭前輩的這篇文章里,利用比喻把他的方法原理表述的很清楚,簡單來說:他將動畫分成了兩半,如果以本文前面頁面圖中右邊的圓餅作為例子的話,前半動畫是深藍色由12點鐘位置開始逆時針旋轉至-360deg,最后將橙色覆蓋;后半動畫剛好相反,橙色由12點鐘位置開始逆時針旋轉至-360deg,最后將深藍色覆蓋。由于兩半部分動畫的過程是相同的,所以將前半部分動畫制作完成后,將該動畫過程復制一份,將顏色對調,重新套入相同結構的新元素中,再將新的一套重疊在舊一套元素所占區域,設置前半段時間第一套元素顯示、第二套元素透明,后半段時間第二套元素顯示、第一套元素透明。這樣就完成了圓餅loading效果。
下面以前半部分動畫為例表述下動畫過程:

首先需要了解html結構(以本文開始所列html結構為例),設置類名為inner的span作為父元素,該元素背景為深藍色,其下同列三個span作為子元素,類名分別為:spiner、filler、masker。以上四者中,按照原理,.filler、.masker的z-index應該設置得高于.spiner,但在實際設置中,張鑫旭前輩沒有設置z-index值,而是利用在html結構中將需要優先顯示的元素并列在后面的方式(如果在html結構中將.masker與.spiner對調,就會出現錯誤),規避了這點。.masker為左半圓,深藍色;.filler為右半圓,橙色;.spiner為旋轉半圓,橙色,初始位置位于左半部分。

a.初始狀態:.masker透明,此時由.spiner和.filler分別位于左右方拼接成橙色圓餅:

b.此時,.spiner開始圍繞圓心逆時針旋轉,則作為父元素的.inner開始從12點鐘方向逆時針顯露(深藍色),到.spiner旋轉-180deg時,.masker由透明變為顯示,.filler由顯示變為透明:

c.之后,.spiner繼續逆時針旋轉,由于.filler已經透明,則.inner從6點鐘方向逆時針顯露,而左半圓區域由于.masker已經顯示(z-index值比.spiner大),也為深藍色,這樣,當.spiner旋轉一周之后,就由橙色全部變為藍色:

以上為動畫原理,css代碼過長,請見文末demo代碼地址。在實現這個方法的過程中,還需要注意,要變化透明度的元素(.inner/.inner2/.masker/.filler),其透明度變化并不是漸變,而是突變,所以需要設置animation-timing-function為steps()突變曲線,steps(n,start/end)主要有兩個值,簡單來說,n設置突變次數(整數),start/end設置在動畫開始還是結束突變。

思考:

1.利用steps()曲線,可以制作一些更炫酷的css3動畫。并且,在同一個方向上連續漸變的動畫,由于漸變位置不同,通常需要兩個以上元素實現,但利用steps()曲線突變位置,就能通過一個元素實現了;
2.完成以上任務之后,可以優化的地方:第一個方法中的.spining子元素,可以使用偽元素替代;同理,第二個方法中的子元素,也可用偽元素替代;
3.圓環除了定長旋轉,也可根據圓餅loading旋轉的方法,實現變長旋轉loading效果。

具體參考已在文中引出,不再單列,以下為我的demo及demo代碼:

我的demo;
  demo代碼;

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 發現 關注 消息 iOS 第三方庫、插件、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,229評論 4 61
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,263評論 25 708
  • 原文地址:→看過來 寫在前面 (附錄有源碼及效果) 之前碰到一個小練習,就是用純CSS3來寫餅狀的loading效...
    樓心漫閱讀 3,293評論 10 29
  • 如果這樣真的算是失眠的話,已經好多年。最喜歡深夜。年少輕狂的時候,喜歡這種沒有偽裝虛妄的夜幕,肆意的享受著難得的自...
    Maxdiane閱讀 328評論 0 0
  • 2017.6.21寫簡書的第12天 前幾天在微博上看搞笑視屏,那個微博博主轉載了一篇文章,標題是習慣可以成就你也可...
    隔壁小志龍閱讀 321評論 0 1