CSS3+JS實現靜態圓形進度條【清晰、易懂】

在寫這篇文章以前,筆者查看了多篇博客,無奈前輩大多隻是貼了代碼,沒有清晰明瞭的註釋,因此容易讓新人看得雲裏霧裏。這裏,筆者在弄明白原理後,對代碼進行了優化,決定寫(總結)一篇清晰、明瞭的圓形進度條的實現,以便後人能快速搞懂。css

1、實現原理

首先,咱們來一個(黑色)。
接着,再來兩個半圓,將黑色的圓遮住。(爲了演示,左右兩側顏色不同)
這時候,咱們順時針旋轉右側藍色的半圓,下面的黑色圓就會暴露出來,好比咱們旋轉45度(12.5%),效果出來了。
若是咱們將藍色的右半圓一樣設置成灰色,看效果,一個12.5%的餅圖就出來了!html

clipboard.pngclipboard.pngclipboard.pngclipboard.png

OK,咱們再旋轉更大的度數試試,好比40%(144度),50%(180度),60%(216度)以下圖。
咱們發現,旋轉180度以後右半圓與左半圓重合了,若是再旋轉,就會在右上角冒出來,顯然不是咱們想要的。node

clipboard.pngclipboard.pngclipboard.png

咱們但願的是,繼續旋轉被黑色遮住。。。嗯。。。怎麼作呢?css3

咱們將右側的圓迴歸原位,把它刷成黑色(和底色同樣),而後旋轉左邊的半圓(它在右側半圓的更底層),這樣,它就會被右側半圓遮住了。好的,廢話很少說,咱們將左側的半圓順時針旋轉45度,效果出來了。能夠想象,繼續旋轉,180度的時候,就徹底被右側半圓遮住,而左側底色所有暴露,這樣100%顯示出來了。web

clipboard.pngclipboard.png
clipboard.png

最後,加上一個白色的小圓,放在正中間就好了。bootstrap

好的,到這裏,咱們已經明白如何實現的了。api

2、代碼實現

html部分瀏覽器

<div class="circle-bar">
    <div class="circle-bar-left"></div>
    <div class="circle-bar-right"></div>
    <!-- 遮罩層,顯示百分比 -->
    <div class="mask">
        <span class="percent">60%</span>
    </div>
</div>

css部分函數

/*支持IE9及以上*/
    .circle-bar { font-size:200px; width: 1em; height: 1em; position: relative;  background-color: #333; }
    .circle-bar-left,.circle-bar-right { width: 1em; height: 1em; background-color: #eee; }
    /*
        這裏採用clip剪切了圓,實現左右兩個半圓,右半圓在後面,所以在更上一層,
        clip的用法參考:http://www.w3school.com.cn/cssref/pr_pos_clip.asp
     */
    .circle-bar-right { clip:rect(0,auto,auto,.5em); }
    .circle-bar-left { clip:rect(0,.5em,auto,0); }
    
    .mask { width: 0.8em; height: 0.8em;  background-color: #fff;text-align: center;line-height: 0.2em; color:rgba(0,0,0,0.5); }
    .mask :first-child { font-size: 0.3em; height: 0.8em; line-height: 0.8em; display: block;  }
    /*全部的後代都水平垂直居中,這樣就是同心圓了*/
    .circle-bar * {  position: absolute; top:0; right:0; bottom:0; left:0; margin:auto; }
    /*自身以及子元素都是圓*/
    .circle-bar, .circle-bar > * { border-radius: 50%; }

JavaScript實現學習

//反正CSS3中的border-radius屬性IE8是不支持了,因此這裏就用新方法吧getElementsByClassName()走起
    window.onload = function(){

        var circleBar    = document.getElementsByClassName('circle-bar')[0];
        var percent      = parseInt(circleBar.getElementsByClassName('percent')[0].firstChild.nodeValue);
        var color        = circleBar.css('background-color');
        var left_circle  = circleBar.getElementsByClassName('circle-bar-left')[0];
        var right_circle = circleBar.getElementsByClassName('circle-bar-right')[0];

        if( percent <= 50 ) {
            var rotate = 'rotate('+(percent*3.6)+'deg)';
            right_circle.css3('transform',rotate);
        }else {
            var rotate = 'rotate('+((percent-50)*3.6)+'deg)';
            right_circle.css ('background-color',color);//背景色設置爲進度條的顏色
            right_circle.css3('transform','rotate(0deg)');//右側不旋轉
            left_circle.css3 ('transform',rotate);//左側旋轉
        }
    }

    //封裝了css3函數,主要是懶得重複書寫代碼,既然寫了css3函數,順便寫個css吧,統同樣式,好看一些
    Element.prototype.css = function(property,value){
        
        if ( value ) {
            //CSS中像background-color這樣的屬性,‘-’在JavaScript中不兼容,須要設置成駝峯格式
            var index = property.indexOf('-');
            if( index != -1 ) {
                var char = property.charAt(index+1).toUpperCase();
                property.replace(/(-*){1}/,char);
            }
            this.style[property] = value;
        }else{
            //getPropertyValue()方法參數相似background-color寫法,因此不要轉駝峯格式
            return window.getComputedStyle(this).getPropertyValue(property);
        }
    }

    //封裝一個css3函數,用來快速設置css3屬性
    Element.prototype.css3 = function(property,value){
        if( value ){
            property = capitalize(property.toLowerCase());
            this.style['webkit'+property] = value;
            this.style['Moz'+property] = value;
            this.style['ms'+property] = value;
            this.style['O'+property] = value;
            this.style[property.toLowerCase()] = value;
        }else{
            return window.getComputedStyle(this).getPropertyValue(
                    ('webkit'+property)||('Moz'+property)||('ms'+property)||('O'+property)||property);
                    //老實說,我不知道爲何要把不帶瀏覽器標記的放在最後,既然都這麼用,我也這麼作吧。不過這樣對現代瀏覽器來講可能並很差,判斷次數變多了
        }
        
        //首字母大寫
        function capitalize(word){
            return word.charAt(0).toUpperCase() + word.slice(1);
        }
    }

jQuery實現

$(function(){

        var percent = parseInt($('.mask :first-child').text());
        var baseColor = $('.circle-bar').css('background-color');

        if( percent<=50 ){
            $('.circle-bar-right').css('transform','rotate('+(percent*3.6)+'deg)');
        }else {
            $('.circle-bar-right').css({
                'transform':'rotate(0deg)',
                'background-color':baseColor
            });
            $('.circle-bar-left').css('transform','rotate('+((percent-50)*3.6)+'deg)');
        }
    })

jQuery這麼簡單好用,爲何還要寫JavaScript?

一來,學習JavaScript的使用,畢竟有些方法多是不太熟悉的,多查查文檔,混個眼熟。
二來,萬一項目中不須要使用jQuery呢,之後還得實現。

3、總結體會

在規定圓的大小的時候,使用了font-size屬性,而長度大小則基於font-size,也就是em爲單位,這樣有一個好處,只要修改font-size的值,就能夠改變圓的大小了,很是方便。

另外,寫css的時候,儘量將相同功能的代碼提取出來,將某個功能寫在一個{}中,起一個好名字,之後方便複用,bootstrap就是這麼玩的,簡潔、易讀,經過classname基本就能知道標籤有哪些特性了。

相關文章
相關標籤/搜索