用css3制作旋轉加載動畫的幾種方法


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

方案1,圖片輔助

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

@-webkit-keyframes rotate {
  from {-webkit-transform:rotate(0deg);}
  to {-webkit-transform:rotate(360deg);}
}
p#spinner {
  height: 30px;
  width: 30px;
  overflow: hidden;
  background: #000;
  -webkit-mask-image: url("data:image/png[...]");
  -webkit-mask-size: 30px 30px;
  -webkit-animation-name: rotate;
  -webkit-animation-duration: 1.5s;
  -webkit-animation-iteration-count: infinite;
  -webkit-animation-timing-function: linear;
}

具體效果查看這里:Demo1

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

方案2, 純CSS實現

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

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

@-webkit-keyframes fade {
    from {opacity: 1;}
    to {opacity: 0.25;}
}
div.spinner {
    position: relative;
    width: 30px;
    height: 30px;
    display: inline-block;
}
div.spinner div {
    width: 20%;
    height: 40%;
    background: #000;
    position: absolute;
    left: 100%;
    top: 100%;
    opacity: 0;
    -webkit-animation: fade 1s linear infinite;
    -webkit-border-radius: 30px;
}
div.spinner div.bar1 {
    -webkit-transform:rotate(0deg) translate(0, -142%);
        -webkit-animation-delay: 0s;
}
[......]
div.spinner div.bar12 {
    -webkit-transform:rotate(330deg) translate(0, -142%); 
    -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的效果。

.x-loading-spinner {
    font-size: 250%;
    height: 1em;
    width: 1em;
    position: relative;
    -webkit-transform-origin: 0.5em 0.5em;
}
.x-loading-spinner > span, .x-loading-spinner > span:before, .x-loading-spinner > span:after {
    display: block;
    position: absolute;
    width: 0.1em;
    height: 0.25em;
    top: 0;
    -webkit-transform-origin: 0.05em 0.5em;
    -webkit-border-radius: 0.05em;
    border-radius: 0.05em;
    content: " ";
}
.x-loading-spinner > span.x-loading-top {
    background-color: rgba(170, 170, 170, 0.99);
}
.x-loading-spinner > span.x-loading-top::after {
    background-color: rgba(170, 170, 170, 0.9);
}
.x-loading-spinner > span.x-loading-left::before {
    background-color: rgba(170, 170, 170, 0.8);
}
.x-loading-spinner > span.x-loading-left {
    background-color: rgba(170, 170, 170, 0.7);
}
.x-loading-spinner > span.x-loading-left::after {
    background-color: rgba(170, 170, 170, 0.6);
}
.x-loading-spinner > span.x-loading-bottom::before {
    background-color: rgba(170, 170, 170, 0.5);
}
.x-loading-spinner > span.x-loading-bottom {
    background-color: rgba(170, 170, 170, 0.4);
}
.x-loading-spinner > span.x-loading-bottom::after {
    background-color: rgba(170, 170, 170, 0.35);
}
.x-loading-spinner > span.x-loading-right::before {
    background-color: rgba(170, 170, 170, 0.3);
}
.x-loading-spinner > span.x-loading-right {
    background-color: rgba(170, 170, 170, 0.25);
}
.x-loading-spinner > span.x-loading-right::after {
    background-color: rgba(170, 170, 170, 0.2);
}
.x-loading-spinner > span.x-loading-top::before {
    background-color: rgba(170, 170, 170, 0.15);
}
.x-loading-spinner > span {
    left: 50%;
    margin-left: -0.05em;
}
.x-loading-spinner > span.x-loading-top {
    -webkit-transform: rotate(0deg);
    -moz-transform: rotate(0deg);
}
.x-loading-spinner > span.x-loading-right {
    -webkit-transform: rotate(90deg);
    -moz-transform: rotate(90deg);
}
.x-loading-spinner > span.x-loading-bottom {
    -webkit-transform: rotate(180deg);
    -moz-transform: rotate(180deg);
}
.x-loading-spinner > span.x-loading-left {
    -webkit-transform: rotate(270deg);
    -moz-transform: rotate(270deg);
}
.x-loading-spinner > span::before {
    -webkit-transform: rotate(30deg);
    -moz-transform: rotate(30deg);
}
.x-loading-spinner > span::after {
    -webkit-transform: rotate(-30deg);
    -moz-transform: rotate(-30deg);
}
.x-loading-spinner {
    -webkit-animation-name: x-loading-spinner-rotate;
    -webkit-animation-duration: 0.5s;
    -webkit-animation-iteration-count: infinite;
    -webkit-animation-timing-function: linear;
}

@-webkit-keyframes x-loading-spinner-rotate {
    from {
    -webkit-transform: rotate(30deg);
    }
    to {
    -webkit-transform: rotate(330deg);
    }
}

具體效果查看這里:Demo3

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

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

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM