以WebKit為核心的瀏覽器,例如Safari和Chrome,對html5有著很好的支援,在移動平臺中這兩個瀏覽器對應的就是IOS和Android。最近在開發一個移動平臺的web app,那麼就有機會利用css3去實現一些很酷的效果,這些效果原來更多的是利用圖片來實現。最近的一個改進就是利用css3製作旋轉載入動畫。以下將分別介紹幾種實現的方案。

方案1,圖片輔助

傳統做法是直接用動態的GIF圖片,這個方案是用PNG圖片加上背景顏色來模擬靜止的載入圖片,然後利用css中的animation處理圖片的旋轉。相比傳統方案,這個方案的好處是可以直接通過修改CSS來改變背景色,可以修改大小和旋轉速度。如下是具體的CSS程式碼:

 

  1. @-webkit-keyframes rotate { 
  2.   from {-webkit-transform:rotate(0deg);} 
  3.   to {-webkit-transform:rotate(360deg);} 
  4. p#spinner { 
  5.   height: 30px; 
  6.   width: 30px; 
  7.   overflow: hidden; 
  8.   background: #000; 
  9.   -webkit-mask-p_w_picpath: url("data:p_w_picpath/png[...]"); 
  10.   -webkit-mask-size: 30px 30px; 
  11.   -webkit-animation-name: rotate; 
  12.   -webkit-animation-duration: 1.5s; 
  13.   -webkit-animation-iteration-count: infinite; 
  14.   -webkit-animation-timing-function: linear; 

具體效果檢視這裡:Demo1

這個方案,只有safari可以很好地支援。chrome下支援不是很好,所以這是一個不太成熟的方案。

方案2, 純CSS實現

方案的思路是,首先用css渲染12個靜態的bar,每個bar間隔30度的角度,給每個bar新增背景變淡的動畫,但是相鄰bar的動畫效果延遲1/12秒,來保證12個bar是按順序變亮然後變暗。從而模擬出旋轉的效果。

這個旋轉效果是偽旋轉,所有的bar都沒有真正做到旋轉。

 

  1. @-webkit-keyframes fade { 
  2.     from {opacity: 1;} 
  3.     to {opacity: 0.25;} 
  4. div.spinner { 
  5.     position: relative; 
  6.     width: 30px; 
  7.     height: 30px; 
  8.     display: inline-block; 
  9. div.spinner div { 
  10.     width: 20%; 
  11.     height: 40%; 
  12.     background: #000; 
  13.     position: absolute; 
  14.     left: 100%; 
  15.     top: 100%; 
  16.     opacity: 0; 
  17.     -webkit-animation: fade 1s linear infinite; 
  18.     -webkit-border-radius: 30px; 
  19. div.spinner div.bar1 { 
  20.     -webkit-transform:rotate(0deg) translate(0, -142%); 
  21.         -webkit-animation-delay: 0s; 
  22. [......] 
  23. div.spinner div.bar12 { 
  24.     -webkit-transform:rotate(330deg) translate(0, -142%);  
  25.     -webkit-animation-delay: -0.0833s; 

具體效果檢視這裡:Demo2

safari和chrome都能很好地渲染這個效果,並且也很容易定義實際大小,因為所有的bar的高度,寬度有是用百分比來定義的。缺點也很明顯,需要定義12個bar,並且每個bar都要定義獨立的css,相對來說html和css的程式碼量有點多。

方案3,這個方案類似sencha touch中實現的效果

方案的基本思想是:首先利用html和css呈現4個bar,再通過css的偽元素: before和:after定義每個bar的前後內容,這樣使得由原始的4個bar產生12個bar的效果,其次通過css設定讓12個bar的透明度逐漸遞減,最後應用css3中旋轉動畫達到實際loading的效果。

 

  1. .x-loading-spinner { 
  2.     font-size: 250%; 
  3.     height: 1em; 
  4.     width: 1em; 
  5.     position: relative; 
  6.     -webkit-transform-origin: 0.5em 0.5em; 
  7. .x-loading-spinner > span, .x-loading-spinner > span:before, .x-loading-spinner > span:after { 
  8.     display: block; 
  9.     position: absolute; 
  10.     width: 0.1em; 
  11.     height: 0.25em; 
  12.     top: 0; 
  13.     -webkit-transform-origin: 0.05em 0.5em; 
  14.     -webkit-border-radius: 0.05em; 
  15.     border-radius: 0.05em; 
  16.     content: " "; 
  17. .x-loading-spinner > span.x-loading-top { 
  18.     background-color: rgba(170, 170, 170, 0.99); 
  19. .x-loading-spinner > span.x-loading-top::after { 
  20.     background-color: rgba(170, 170, 170, 0.9); 
  21. .x-loading-spinner > span.x-loading-left::before { 
  22.     background-color: rgba(170, 170, 170, 0.8); 
  23. .x-loading-spinner > span.x-loading-left { 
  24.     background-color: rgba(170, 170, 170, 0.7); 
  25. .x-loading-spinner > span.x-loading-left::after { 
  26.     background-color: rgba(170, 170, 170, 0.6); 
  27. .x-loading-spinner > span.x-loading-bottom::before { 
  28.     background-color: rgba(170, 170, 170, 0.5); 
  29. .x-loading-spinner > span.x-loading-bottom { 
  30.     background-color: rgba(170, 170, 170, 0.4); 
  31. .x-loading-spinner > span.x-loading-bottom::after { 
  32.     background-color: rgba(170, 170, 170, 0.35); 
  33. .x-loading-spinner > span.x-loading-right::before { 
  34.     background-color: rgba(170, 170, 170, 0.3); 
  35. .x-loading-spinner > span.x-loading-right { 
  36.     background-color: rgba(170, 170, 170, 0.25); 
  37. .x-loading-spinner > span.x-loading-right::after { 
  38.     background-color: rgba(170, 170, 170, 0.2); 
  39. .x-loading-spinner > span.x-loading-top::before { 
  40.     background-color: rgba(170, 170, 170, 0.15); 
  41. .x-loading-spinner > span { 
  42.     left: 50%; 
  43.     margin-left: -0.05em; 
  44. .x-loading-spinner > span.x-loading-top { 
  45.     -webkit-transform: rotate(0deg); 
  46.     -moz-transform: rotate(0deg); 
  47. .x-loading-spinner > span.x-loading-right { 
  48.     -webkit-transform: rotate(90deg); 
  49.     -moz-transform: rotate(90deg); 
  50. .x-loading-spinner > span.x-loading-bottom { 
  51.     -webkit-transform: rotate(180deg); 
  52.     -moz-transform: rotate(180deg); 
  53. .x-loading-spinner > span.x-loading-left { 
  54.     -webkit-transform: rotate(270deg); 
  55.     -moz-transform: rotate(270deg); 
  56. .x-loading-spinner > span::before { 
  57.     -webkit-transform: rotate(30deg); 
  58.     -moz-transform: rotate(30deg); 
  59. .x-loading-spinner > span::after { 
  60.     -webkit-transform: rotate(-30deg); 
  61.     -moz-transform: rotate(-30deg); 
  62. .x-loading-spinner { 
  63.     -webkit-animation-name: x-loading-spinner-rotate; 
  64.     -webkit-animation-duration: 0.5s; 
  65.     -webkit-animation-iteration-count: infinite; 
  66.     -webkit-animation-timing-function: linear; 
  67.  
  68. @-webkit-keyframes x-loading-spinner-rotate { 
  69.     from { 
  70.     -webkit-transform: rotate(30deg); 
  71.     } 
  72.     to { 
  73.     -webkit-transform: rotate(330deg); 
  74.     } 

具體效果檢視這裡:Demo3

這個方案是3個方案中應用css技術最徹底的一個,html的程式碼最少,並且也真正做到了旋轉效果。缺點是不易擴充套件,chrome瀏覽器支援不是很理想。

綜上分析,方案1瀏覽器支援不好,但是實現簡單,方案2的html程式碼太多,但擴充套件好,瀏覽器支援不錯,方案3的擴充套件性不好,瀏覽器支援也不好,但是較好地利用了css的特性。

如果開發桌面web系統,推薦方案2,如果是mobile系統,則方案2和方案3各有優勢。