css3 製作圓環進度條

凜冬將至發表於2019-02-16

引子

移動端做一個 loadiing 載入的圖示,跟以往沿用的都不太一樣,是一個圓環進度條,圓環進度條也就罷了,還得能用百分比控制。

CSS3 實現圓環

demo

剛開始寫這個圓環的時候是參照帖子上給出的css程式碼代入,然後根據自己的需求改,發現圓環可以完美轉動了,但是好像沒法用百分比控制,所以放棄了隨便copy一個現成的想法,該動動腦子還是有必要的。

實現原理

css實現圓環的方法很多,我看大部分都是採用邊框(border)+ 裁剪(clip:rect())來實現的,所以我也準備採用這種方式。

主要是佈局問題,我看大部分圓環進度條都大同小異,就是佈局和轉動方式不同

// html 

<div id="loading" class="loading">
    <div class="circle">
        <div class="percent left"></div>
        <div class="percent right wth0"></div>
    </div>
    <div class="per"></div>
</div>

// css 

.loading {
  position: fixed;
  top: 50%;
  left: 50%;
  overflow: hidden;
  z-index: 9999;
  -webkit-transform: translate(-50%,-50%);
          transform: translate(-50%,-50%);
}
.circle{
  -webkit-box-sizing: border-box;
     -moz-box-sizing: border-box;
          box-sizing: border-box;
  border:10px solid #fff;
  clip:rect(0,100px,100px,50px);
}
.clip-auto{
  clip:rect(auto, auto, auto, auto);
}
.percent{
  -webkit-box-sizing: border-box;
     -moz-box-sizing: border-box;
          box-sizing: border-box;
  top:-10px;
  left:-10px;
}
.left{
  -webkit-transition:-webkit-transform ease;
  transition:-webkit-transform ease;
  transition:transform ease;
  border:10px solid #E54B00;
  clip: rect(0,50px,100px,0);
}
.right{
  border:10px solid #E54B00;
  clip: rect(0,100px,100px,50px);
}
.wth0{
  width:0;
}

// js


$(`.left`).animate({
    deg: per*3.6
}, {
    step: function(n, fx) {
        if(per>180){
            $(`.circle`).addClass(`clip-auto`);
            $(`.right`).removeClass(`wth0`);
        }
        $(this).css({
            "-webkit-transform":"rotate("+n+"deg)",
            "-moz-transform":"rotate("+n+"deg)",
            "transform":"rotate("+n+"deg)"
        });
    },
    duration:500
})

通過對 .circle(左右兩側圓環的父元素) 的裁剪只顯示左側的圓環,右側的圓環的寬度直接為 0 ,當進度條進行到50%的時候,即左側圓環轉動角度為 transform: rotate(180deg) ,將 .circle 的裁剪去掉 (.clip-auto),右側圓環的寬度恢復。基本就是這個套路。

jQuery的 動畫方法 animate() 的 step屬性

如果僅用

$(this).css({
    "-webkit-transform":"rotate("+n+"deg)",
    "-moz-transform":"rotate("+n+"deg)",
    "transform":"rotate("+n+"deg)"
});

來控制角度的轉動,沒有絲毫動畫顯得比較生硬,這時候就要考慮給它加個動畫了,而jq提供的 animate 對只有數字值可建立動畫,而字串型別的值無法建立動畫。

這時候需要用到 animate的step屬性了。

step介紹

animate的progress屬性是我們經常用的,對數字值的屬性進行操作,但是字串值的屬性卻並不能用它進行操作,這時候就需要step屬性了。

step 顧名思義就是對一段動畫進行步驟分解,在animate方法中,每一步具體是怎麼分解的,不是由我們設定的CSS屬性值和動畫時長來決定的,是由系統來決定的。

$(".left").animate({left:50},{
    duration:100,
    step:function(now,fx){
        console.log(now) //控制檯輸出,看看這個動畫被分解成了幾個片段
    }
});

這個地方主要是解釋為什麼在這裡給角度賦值,順便說明一下它到底將該值分成多少個片段並不是由我們人為控制的。

step方法的第二個引數——fx

$(".demo").animate({
    first:2,
    second:10
}, {
    step:function(n,fx){
        // 動畫元素的每個動畫屬性每一次動畫效果的執行都將呼叫的函式。第1個引數是當前動畫正在改變的屬性的實時值(每1次動畫過程中,屬性值的實時反饋呈現);第2個引數為修改Tween 物件提供了一個機會來改變animate第1個引數中設定的屬性在動畫結束時的值。
        // fx: jQuery.fx 原型物件的一個引用,其中包含了多項屬性,比如
        // 執行動畫的元素:elem;
        // 動畫正在改變的屬性:prop;
        // 正在改變屬性的當前值:now;
        // 正在改變屬性的結束值:end;
        // 正在改變屬性的單位:unit;等
        
        // 可在這裡改變animate第1個引數中設定的屬性second在動畫結束時的值
        if(fx.prop=="second"){fx.end=5}
        console.log(fx.prop+": "+n);
    },
    duration:2000
})

結束

做這個動畫遇到了自己兩個知識盲點,clip的運用以及jq的step屬性,寫這篇文章主要目的還是加深理解,以及分享。

相關文章