1. 程式人生 > >css3實現圓形進度載入動畫

css3實現圓形進度載入動畫

使用到的css3屬性有border-radius,transform,animation,clip等,在這裡著重講一下clip這個屬性。因為博主也是第一次用這個屬性。。。

這個屬性就是規定盒子內顯示的區域,可以有的值有auto(預設),有inherit:從父類繼承,還有就是新增rect(top,right,bottom,left)。就是規定一下顯示區域,只有盒子內從盒子的左上角的頂點做位置對比,只有在這四個值內的區域才能夠顯示出來。

重點:這個屬性必須在絕對定位absolute或基於瀏覽器定位時fixed情況下,才管用。

具體情況還是自己測試一下,就全明白了。這個屬性沒有過渡效果,如果寫到動畫當中,它會從切換開始時間和切換時間取中間值,直接切換過去。


下面先上一個實現後的效果的程式碼,然後我還會再寫一個封裝好的程式碼,以便懶人使用。

<!doctype html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .div{
            position: absolute;
            left:0;
            top:0;
            width:100%;
            height: 100%;
            border-radius: 50%;
            border:10px solid rgba(0,0,0,0);
            box-sizing: border-box;
        }

        .left,.right{
            border-right-color: rgba(0,0,0,0);
            border-bottom-color: rgba(0,0,0,0);
            transform: rotate(-45deg);
        }

        #circle.hover .left{
            border-left:10px solid #1caffc;
            border-top:10px solid #1caffc;
            animation: left-animation 5s linear;
        }

        #circle.hover .right{
            border-left:10px solid #1caffc;
            border-top:10px solid #1caffc;
            animation: right-animation 5s linear;
        }

        #circle{
            top:200px;
            left:40%;
            width:200px;
            height: 200px;
            border-width: 0;
            clip:rect(0px,200px,200px,100px);
        }

        #circle.hover{
            animation: circle-animation 5s linear;
        }

        @keyframes circle-animation {
            0%{clip:rect(0px,200px,200px,100px);}
            100%{clip:auto;}
        }

        @keyframes left-animation {
            0%{transform: rotate(-45deg);}
            50%{transform: rotate(135deg);}
            100%{transform: rotate(315deg);}
        }

        @keyframes right-animation {
            0%{transform: rotate(-45deg);}
            50%{transform: rotate(135deg);}
            100%{transform: rotate(135deg);}
        }

    </style>
</head>
<body>
    <div class="div hover" id="circle">
        <div class="right div"></div>
        <div class="left div"></div>
    </div>
</body>
</html>

下午因為專案需求,書寫了一個建構函式,支援一些屬性的修改,由於用了一下午,比較粗糙,湊合著用吧。只要把函式引入,例項化的時候設定將div的id傳入,注意,一定要給div設定定位屬性position為absolute或者fixed才管用。

<!doctype html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>

        #circle{
            position: absolute;
            left:45%;
            top:200px;
        }

    </style>
</head>
<body>
    <div id="circle">
    </div>
</body>
<script>
    function Loading(setting) {
        this.settings ={
            animationTime:5,//動畫執行時間
            divId:"circle",//div盒子的id
            divWidth:"200px",//盒子的寬度
            divHeight:"200px", // 盒子的高度
            divClassName: "active", //新增class名字後就會執行載入動畫
            leftDivName:"left", //第一個盒子的class名字
            rightDivName:"right", //內部第二個盒子的class名字
            infinite:true, // 是否迴圈
            loadingWidth:"10px", //圓圈寬度
            loadingColor:"#000" //圓圈的顏色

        };

        this.timeOut = null; //延遲器

        if(setting){
            for(var i in setting){
                this.settings[i] = setting[i];
            }
        }


        this.prefix = function () {
            var div = document.createElement('div');
            var cssText = '-webkit-transition:all .1s; -moz-transition:all .1s; -o-transition:all .1s; -ms-transition:all .1s; transition:all .1s;';
            div.style.cssText = cssText;
            var style = div.style;
            if (style.webkitTransition) {
                return '-webkit-';
            }
            if (style.MozTransition) {
                return '-moz-';
            }
            if (style.oTransition) {
                return '-o-';
            }
            if (style.msTransition) {
                return '-ms-';
            }
            return '';
        };

        this.runOne = function (callback) {
            var that = this;
            //呼叫執行一次
            this.div.classList.add(this.settings.divClassName);
            this.timeOut = setTimeout(function () {
                that.div.classList.remove(that.settings.divClassName);
                callback.call(that.div,that.div);
            },+that.settings.animationTime*1000)
        };

        this.runForever = function () {
            this.div.classList.add(this.settings.divClassName);
        };

        var div = this.div = document.getElementById(this.settings.divId);
        div.style.cssText = "border-radius:50%; width:"+this.settings.divWidth+"; height:"+this.settings.divHeight+"; clip:rect(0,"+div.offsetWidth+"px,"+div.offsetHeight+"px,"+div.offsetWidth/2+"px);;";
        var left = document.createElement("div");
        left.className = this.settings.leftDivName;
        var right = document.createElement("div");
        right.className = this.settings.rightDivName;
        var style = document.createElement("style");
        div.appendChild(left);
        div.appendChild(right);

        style.innerText = "" +
            "@"+this.prefix()+"keyframes circle-animation {" +
            "   0%{clip:rect(0,"+div.offsetWidth+"px,"+div.offsetHeight+"px,"+div.offsetWidth/2+"px);}" +
            "   100%{clip:auto;}" +
            "}\n" +
            "@"+this.prefix()+"keyframes left-animation {" +
            "   0%{transform: rotate(-45deg);}" +
            "   50%{transform: rotate(135deg);}" +
            "   100%{transform: rotate(315deg);}" +
            "}\n" +
            "@"+this.prefix()+"keyframes right-animation {" +
            "   0%{transform: rotate(-45deg);}" +
            "   50%{transform: rotate(135deg);}" +
            "   100%{transform: rotate(135deg);}" +
            "}\n" +
            "#"+this.settings.divId+"."+this.settings.divClassName+"{" +
            "   "+this.prefix()+"animation: circle-animation "+this.settings.animationTime+"s linear "+(this.settings.infinite ? "infinite":"")+";" +
            "}\n" +
            "#"+this.settings.divId+" ."+this.settings.leftDivName+",#"+this.settings.divId+" ."+this.settings.rightDivName+"{" +
            "   border-left:"+this.settings.loadingWidth+" solid "+this.settings.loadingColor+";" +
            "   border-top:"+this.settings.loadingWidth+" solid "+this.settings.loadingColor+";" +
            "   border-right:"+this.settings.loadingWidth+" solid rgba(0,0,0,0);" +
            "   border-bottom:"+this.settings.loadingWidth+" solid rgba(0,0,0,0);" +
            "   transform: rotate(-45deg);" +
            "   position:absolute;" +
            "   left:0;" +
            "   top:0;" +
            "   width:100%;" +
            "   height:100%;" +
            "   border-radius:50%;" +
            "   box-sizing:border-box;" +
            "}\n" +
            "#"+this.settings.divId+"."+this.settings.divClassName+" ."+this.settings.leftDivName+"{" +
            "   "+this.prefix()+"animation: left-animation "+this.settings.animationTime+"s linear "+(this.settings.infinite ? "infinite":"")+
            "}\n" +
            "#"+this.settings.divId+"."+this.settings.divClassName+" ."+this.settings.rightDivName+"{" +
            "   "+this.prefix()+"animation: right-animation "+this.settings.animationTime+"s linear "+(this.settings.infinite ? "infinite":"")+
            "}\n" +
            "";

        document.head.appendChild(style);
    }

    var obj = new Loading({divId:"circle"}); //例項化建構函式
    obj.runOne(function () { //只執行一次,外加傳入一個匿名函式
        console.log("動畫執行完成");
        obj.runForever(); // 呼叫一直執行的函式
    });


</script>
</html>