寫在前面:
這是一篇菜鳥的學(xué)習(xí)筆記,記錄效果實(shí)現(xiàn)過程,而沒有考慮安全、兼容、性等問題。供新手參考,也希望前輩們指點(diǎn)。
這篇文章將一步一步記錄實(shí)現(xiàn)一個(gè)Material Design的Loading動(dòng)畫,該效果模仿自Materialize網(wǎng)站的Loading動(dòng)畫,效果如下:
實(shí)現(xiàn)的小思路:
之前一直在想通過border的方法只能是實(shí)現(xiàn)一個(gè)完整的圓圈(或缺n*45°的圓圈),但是上面的效果明顯是一個(gè)可變長(zhǎng)度的圓圈的一部分,那么該如何實(shí)現(xiàn)呢?后來查看了下Materialize網(wǎng)站Loading部分的css布局。發(fā)現(xiàn)原來是另一種思路的實(shí)現(xiàn)。Materialize是通過一個(gè)小div設(shè)置overflow:hidden屬性將圓圈的一半給擋住,然后在同個(gè)border-left等屬性使圓圈只有一半,這樣結(jié)合transform: rotate()屬性選擇這一半的圓圈就可以實(shí)現(xiàn)非完整圓圈了。而實(shí)際上實(shí)現(xiàn)上圖任意程度的非完整圓圈,需要使用兩個(gè)div分別各占布局的左右以及兩個(gè)半圓來實(shí)現(xiàn)。具體如何使用,參考詳解用CSS3制作圓形滾動(dòng)進(jìn)度條動(dòng)畫效果
第一部分動(dòng)畫(去掉外布局旋轉(zhuǎn)的效果)
- 先來看看Materialize的效果:
- 我的實(shí)現(xiàn)效果:
- 我的實(shí)現(xiàn)思路:
大布局下分為兩個(gè)div,兩個(gè)div下又有各自的圓圈。同時(shí)設(shè)置旋轉(zhuǎn)動(dòng)畫以達(dá)到該效果。
- 實(shí)現(xiàn)代碼:
<!DOCTYPE html>
<html>
<head>
<mate charset="utf-8"></mate>
<title>Material Design Loading Animation</title>
<style>
/*外層布局*/
.circle-layout{
width: 110px;
height: 110px;
}
/*左div*/
.layout-left{
float: left;
width: 50%;
height: 100%;
overflow: hidden;
position: relative;
}
/*右div*/
.layout-right{
float: right;
width: 50%;
height: 100%;
overflow: hidden;
position: relative;
}
/*左圈*/
.circle-left{
position: absolute;
top: 0;
left: 0;
width: 100px;
height: 100px;
border: 5px solid #F88E8B;
border-radius: 50%;
border-left: 5px solid transparent;
border-bottom: 5px solid transparent;
transform: rotate(40deg);
animation: animation-circle-left 1s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}
/*右圈*/
.circle-right{
position: absolute;
top: 0;
right: 0;
width: 100px;
height: 100px;
border: 5px solid #F88E8B;
border-radius: 50%;
border-right: 5px solid transparent;
border-top: 5px solid transparent;
transform: rotate(-310deg);
animation: animation-circle-right 1s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}
/*左圈動(dòng)畫*/
@keyframes animation-circle-left{
0%{
transform: rotate(40deg);
}
50%{
transform: rotate(-100deg);
}
100%{
transform: rotate(40deg);
}
}
/*右圈動(dòng)畫*/
@keyframes animation-circle-right{
0%{
transform: rotate(-310deg);
}
50%{
transform: rotate(-170deg);
}
100%{
transform: rotate(-310deg);
}
}
</style>
</head>
<body>
<div class="circle-layout">
<div class="layout-left">
<div class="circle-left"></div>
</div>
<div class="layout-right">
<div class="circle-right"></div>
</div>
<div>
</body>
</html>
第二部分動(dòng)畫(加上外層布局旋轉(zhuǎn)的效果)
- 先來看看Materialize的效果:
- 我的實(shí)現(xiàn)效果:
我的實(shí)現(xiàn)思路:
仔細(xì)看就會(huì)發(fā)現(xiàn)這個(gè)動(dòng)畫是先從一個(gè)點(diǎn)往前進(jìn)方向伸張,然后又從尾部開始往前進(jìn)方向收縮成一個(gè)點(diǎn)。那么如何通過上面“去掉外布局旋轉(zhuǎn)的效果”基本動(dòng)畫得到“加上外布局旋轉(zhuǎn)的效果”動(dòng)畫呢?從名字當(dāng)中就可以看出來,答案就是加上外布局的旋轉(zhuǎn)。外布局的動(dòng)畫時(shí)間是基本動(dòng)畫時(shí)間的兩倍,總旋轉(zhuǎn)角度為720°,旋轉(zhuǎn)速度大致與“基本動(dòng)畫”相當(dāng)(本來應(yīng)該是一致,但注意到“基本動(dòng)畫”的圓圈伸張距離并沒有達(dá)到360°,而外布局的動(dòng)畫又要在周期之間灰度過度)。
細(xì)心的人會(huì)注意到“加上外布局旋轉(zhuǎn)的效果”與“動(dòng)畫二”的效果不大一樣:前者的圓圈缺口方向會(huì)改變,二后者的方向一直向上。好吧,我承認(rèn)是我不知道如何做到前者的效果。但看下面“動(dòng)畫三”的效果與Materialize的效果還是比較像的,先這樣湊合用著吧!_代碼實(shí)現(xiàn):
<!DOCTYPE html>
<html>
<head>
<mate charset="utf-8"></mate>
<title>Material Design Loading Animation</title>
<style>
/*外層布局*/
.circle-layout{
width: 110px;
height: 110px;
animation: animation-circle 4s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}
/*左div*/
.layout-left{
float: left;
width: 50%;
height: 100%;
overflow: hidden;
position: relative;
}
/*右div*/
.layout-right{
float: right;
width: 50%;
height: 100%;
overflow: hidden;
position: relative;
}
/*左圈*/
.circle-left{
position: absolute;
top: 0;
left: 0;
width: 100px;
height: 100px;
border: 5px solid #F88E8B;
border-radius: 50%;
border-left: 5px solid transparent;
border-bottom: 5px solid transparent;
transform: rotate(40deg);
animation: animation-circle-left 2s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}
/*右圈*/
.circle-right{
position: absolute;
top: 0;
right: 0;
width: 100px;
height: 100px;
border: 5px solid #F88E8B;
border-radius: 50%;
border-right: 5px solid transparent;
border-top: 5px solid transparent;
transform: rotate(-310deg);
animation: animation-circle-right 2s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}
/*左圈動(dòng)畫*/
@keyframes animation-circle-left{
0%{
transform: rotate(40deg);
}
50%{
transform: rotate(-100deg);
}
100%{
transform: rotate(40deg);
}
}
/*右圈動(dòng)畫*/
@keyframes animation-circle-right{
0%{
transform: rotate(-310deg);
}
50%{
transform: rotate(-170deg);
}
100%{
transform: rotate(-310deg);
}
}
/*外層動(dòng)畫*/
@keyframes animation-circle{
0%{
transform: rotate(0deg);
}
25%{
transform: rotate(180deg);
}
50%{
transform: rotate(360deg);
}
75%{
transform: rotate(540deg);
}
100%{
transform: rotate(720deg);
}
}
</style>
</head>
<body>
<div class="circle-layout">
<div class="layout-left">
<div class="circle-left"></div>
</div>
<div class="layout-right">
<div class="circle-right"></div>
</div>
<div>
</body>
</html>
第三部分動(dòng)畫(在加一個(gè)最外層布局)
- 先來看看Materialize的效果:
- 我的實(shí)現(xiàn)效果:
我的實(shí)現(xiàn)思路:
“動(dòng)畫三”只是在“動(dòng)畫二”的基礎(chǔ)上加上了一層旋轉(zhuǎn),以達(dá)到圓圈缺口方向的變化僅此而已。至于圓圈缺口的變化,讀者可自行修改animation-wrap動(dòng)畫以及animation-circle動(dòng)畫的時(shí)間以調(diào)整效果,但是必須保證animation-circle的動(dòng)畫時(shí)間一定是animation-circle-left/right的兩倍。實(shí)現(xiàn)代碼:
<!DOCTYPE html>
<html>
<head>
<mate charset="utf-8"></mate>
<title>Material Design Loading Animation</title>
<style>
body{
margin: 100px 200px;
}
/*最外層布局*/
.wrap{
width: 110px;
height: 110px;
animation: animation-wrap 2.5s linear infinite;
}
/*外層布局*/
.circle-layout{
width: 110px;
height: 110px;
animation: animation-circle 3s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}
/*左div*/
.layout-left{
float: left;
width: 50%;
height: 100%;
overflow: hidden;
position: relative;
}
/*右div*/
.layout-right{
float: right;
width: 50%;
height: 100%;
overflow: hidden;
position: relative;
}
/*左圈*/
.circle-left{
position: absolute;
top: 0;
left: 0;
width: 100px;
height: 100px;
border: 5px solid #F88E8B;
border-radius: 50%;
border-left: 5px solid transparent;
border-bottom: 5px solid transparent;
transform: rotate(40deg);
animation: animation-circle-left 1.5s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}
/*右圈*/
.circle-right{
position: absolute;
top: 0;
right: 0;
width: 100px;
height: 100px;
border: 5px solid #F88E8B;
border-radius: 50%;
border-right: 5px solid transparent;
border-top: 5px solid transparent;
transform: rotate(-310deg);
animation: animation-circle-right 1.5s cubic-bezier(0.4, 0, 0.2, 1) infinite;
}
/*左圈動(dòng)畫*/
@keyframes animation-circle-left{
0%{
transform: rotate(40deg);
}
50%{
transform: rotate(-100deg);
}
100%{
transform: rotate(40deg);
}
}
/*右圈動(dòng)畫*/
@keyframes animation-circle-right{
0%{
transform: rotate(-310deg);
}
50%{
transform: rotate(-170deg);
}
100%{
transform: rotate(-310deg);
}
}
/*外層動(dòng)畫*/
@keyframes animation-circle{
0%{
transform: rotate(0deg);
}
25%{
transform: rotate(180deg);
}
50%{
transform: rotate(360deg);
}
75%{
transform: rotate(540deg);
}
100%{
transform: rotate(720deg);
}
}
/*最外層動(dòng)畫*/
@keyframes animation-wrap{
0%{
transform: rotate(0deg);
}
100%{
transform: rotate(360deg);
}
}
</style>
</head>
<body>
<div class="wrap">
<div class="circle-layout">
<div class="layout-left">
<div class="circle-left"></div>
</div>
<div class="layout-right">
<div class="circle-right"></div>
</div>
<div>
</div>
</body>
</html>
后續(xù)內(nèi)容
將該效果封裝成可復(fù)用且方便使用的控件,打算使用js動(dòng)態(tài)生成眾多的布局減少html中的代碼量。
更新,2016.10.6
完成后續(xù)內(nèi)容,同時(shí)增加可設(shè)置大小顏色功能
最終效果如下:
是不是和Materialize網(wǎng)站的很接近了。_
代碼如下:
<!DOCTYPE html>
<html>
<head>
<mate charset="utf-8"></mate>
<title>Material Design Loading Animation</title>
<link rel="stylesheet" type="text/css" href="loading.css"></link>
<script type="text/javascript" src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
<script>
$(document).ready(function(){
function LoadingClass(){
this.wrap = jQuery(".mmd-loading-wrap");
this.run = function(){
this.wrap.each(function(i){
//計(jì)算圓圈的寬度
var bw = Math.round($(this).width()/15);
var w = $(this).width() - 2 * bw;
//通過自定義屬性得到圓圈的顏色
var circleColor = $(this).attr("circleColor");
//動(dòng)態(tài)生成圓圈。即將上一個(gè)版本中html的代碼搬移到j(luò)s中,減低html代碼使用量
var div = "<div class='mmd-loading-circle-layout'>"
+"<div class='mmd-loading-layout-left'>"
+"<div class='mmd-loading-circle-left'"
+"style='width:"+w+"px;height:"+w+"px;border-width:"+bw+"px;border-color:"+circleColor+";"
+"border-left:"+bw+"px solid transparent;"+"border-bottom:"+bw+"px solid transparent;'"+"></div>"
+"</div>"
+"<div class='mmd-loading-layout-right'>"
+"<div class='mmd-loading-circle-right'"
+"style='width:"+w+"px;height:"+w+"px;border-width:"+bw+"px;border-color:"+circleColor+";"
+"border-right:"+bw+"px solid transparent;"+"border-top:"+bw+"px solid transparent;'"+"></div>"
+"</div>"
+"</div>";
$(this).append(div);
});
}
}
//自動(dòng)運(yùn)行
(function(){
var loading = new LoadingClass();
loading.run();
})();
});
</script>
</head>
<body>
<!-- 需要設(shè)置circleColor -->
<div class="mmd-loading-wrap" style="width:60px;height:60px;position:absolute;left:300px;top:100px;" circleColor="#F88E8B"></div>
<div class="mmd-loading-wrap" style="width:40px;height:40px;position:absolute;left:500px;top:100px;" circleColor="#DC4C40"></div>
<div class="mmd-loading-wrap" style="width:30px;height:30px;position:absolute;left:700px;top:100px;" circleColor="#26A668"></div>
</body>
</html>