css3實現圓形進度載入動畫
阿新 • • 發佈:2019-01-04
使用到的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>