查看全部代碼請去Githubjavascript
本文出自 「UED」 博客:http://5344794.blog.51cto.com/5334794/1430877css
<!DOCTYPE html> <html> <head> <title>三里屯SOHO商盟</title> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"/> <meta name="apple-mobile-web-app-status-bar-style" content="black"/> <meta name="apple-mobile-web-app-title" content=""/> <meta name="apple-touch-fullscreen" content="YES" /> <meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="format-detection" content="telephone=no" /> <meta name="HandheldFriendly" content="true" /> <meta http-equiv="x-rim-auto-match" content="none" /> <meta name="format-detection" content="telephone=no" /> <!-- This is to force IE into the latest version mode, overriding 'compatibility' mode which breaks everything. --> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <link rel="apple-touch-icon-precomposed" sizes="57x57" href="" /> <link rel="apple-touch-icon-precomposed" sizes="72x72" href="" /> <link rel="apple-touch-icon-precomposed" sizes="114x114" href="" /> <link rel="apple-touch-icon-precomposed" sizes="144x144" href="" /> <link href="assets/css/reset.css" rel="stylesheet" type="text/css"> <link href="assets/css/base.css" rel="stylesheet" type="text/css"> <!--feature--> <link href="assets/css/index.css" rel="stylesheet" type="text/css"> <style type="text/css"> </style> </head> <body> <section class="doc doc--bg2" style="width: 400px;height: 400px;margin: 0 auto;border-radius: 400px;position: relative;border:1px#efefef solid;overflow: hidden;"> <canvas id="canvas" style="position:absolute;top:0px;left:0px;z-index:1;"></canvas> </section> <script type="text/javascript"> var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); canvas.width = canvas.parentNode.offsetWidth; canvas.height = canvas.parentNode.offsetHeight; //若是瀏覽器支持requestAnimFrame則使用requestAnimFrame不然使用setTimeout window.requestAnimFrame = (function(){ return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function( callback ){ window.setTimeout(callback, 1000 / 60); }; })(); //初始角度爲0 var step = 0; //定義三條不一樣波浪的顏色 var lines = ["rgba(0,222,255, 0.2)", "rgba(157,192,249, 0.2)", "rgba(0,168,255, 0.2)"]; function loop(){ ctx.clearRect(0,0,canvas.width,canvas.height); step++; //畫3個不一樣顏色的矩形 for(var j = lines.length - 1; j >= 0; j--) { ctx.fillStyle = lines[j]; //每一個矩形的角度都不一樣,每一個之間相差45度 var angle = (step+j*45)*Math.PI/180; var deltaHeight = Math.sin(angle) * 50; var deltaHeightRight = Math.cos(angle) * 50; ctx.beginPath(); ctx.moveTo(0, canvas.height/2+deltaHeight); ctx.bezierCurveTo(canvas.width /2, canvas.height/2+deltaHeight-50, canvas.width / 2, canvas.height/2+deltaHeightRight-50, canvas.width, canvas.height/2+deltaHeightRight); ctx.lineTo(canvas.width, canvas.height); ctx.lineTo(0, canvas.height); ctx.lineTo(0, canvas.height/2+deltaHeight); ctx.closePath(); ctx.fill(); } requestAnimFrame(loop); } loop(); </script> </body> </html>
首先來看下效果圖。html
要實現這樣的動畫普通的CSS3是鞭長莫及了,只能使用Canvas。好在使用canvas也很是簡單。java
Step1.git
新建一個畫布(<canvas>)元素,並放在在全部按鈕和logo的下方以避免遮擋前面的元素。github
1
|
<
canvas
id
=
"canvas"
style
=
"position:absolute;top:0px;left:0px;z-index:1;"
></
canvas
>
|
將Canvas的寬高設定成其父元素的寬高,以充滿他的父元素。也能夠直接使用window.innerHeight,window.innerWidth。使其充滿整個屏幕。web
1
2
3
4
|
var
canvas = document.getElementById(
'canvas'
);
var
ctx = canvas.getContext(
'2d'
);
canvas.width = canvas.parentNode.offsetWidth;
canvas.height = canvas.parentNode.offsetHeight;
|
Step2.canvas
在畫布中畫一個充滿半個屏幕的矩形。瀏覽器
咱們只須要找到矩形的四個定點的座標,使用Canvas的繪製路徑並填充這個路徑。四個點分別是:app
(0, 畫布高度t/2)
(畫布寬度, 畫布高度t/2)
(畫布寬度 畫布高度t/2)
(0, 畫布高度t/2)
注意:座標的(0,0)在畫布的左上角。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
//填充顏色
ctx.fillStyle =
"rgba(0,222,255, 0.2)"
;
//開始繪製路徑
ctx.beginPath();
//左上角
ctx.moveTo(0, canvas.height/2);
//右上角
ctx.lineTo(canvas.width, canvas.height/2);
//右下角
ctx.lineTo(canvas.width, canvas.height);
//左下角
ctx.lineTo(0, canvas.height);
//左上角
ctx.lineTo(0, canvas.height/2);
//閉合路徑
ctx.closePath();
//填充路徑
ctx.fill();
|
運行代碼:
Step3.
讓矩形動起來。要作動畫咱們須要持續的清空畫布並從新繪製新的矩形,就像電影每秒播放24張圖片。咱們新建一個loop函數,用來繪製每一幀的圖像,並使用requestAnimFrame來告訴瀏覽器每一幀都要使用loop來繪製。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
//若是瀏覽器支持requestAnimFrame則使用requestAnimFrame不然使用setTimeout
window.requestAnimFrame = (
function
(){
return
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function
( callback ){
window.setTimeout(callback, 1000 / 60);
};
})();
function
loop(){
requestAnimFrame(loop);
}
loop();
|
把以前繪製矩形的代碼放到loop中,並在繪製矩形的代碼以前清空畫布中全部的圖形。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
function
loop(){
//清空canvas
ctx.clearRect(0,0,canvas.width,canvas.height);
//繪製矩形
ctx.fillStyle =
"rgba(0,222,255, 0.2)"
;
ctx.beginPath();
ctx.moveTo(0, canvas.height/2);
ctx.lineTo(canvas.width, canvas.height/2);
ctx.lineTo(canvas.width, canvas.height);
ctx.lineTo(0, canvas.height);
ctx.lineTo(0, canvas.height/2);
ctx.closePath();
ctx.fill();
requestAnimFrame(loop);
}
|
接下來咱們更改每一幀中的矩形的高度來模擬波浪的形態,波浪實際上是在波峯與波谷之間作週期性運動。咱們假設波峯與波谷間都是50px,那麼矩形的高度的變化值應該在-50px到50px之間。爲了達到週期性的效果咱們採用正弦函數sin(x),由於無論x值怎麼變化sin(x)的值始終在-1與1之間。咱們新建一個變量 var step =0 使其在每一幀中自增,表示每一幀角度增長一度,並用Math.sin()取他的正弦值。JS中的sin使用的弧度值,咱們須要把step轉換成弧度值,var angle = step*Math.PI/180; 取角度的正弦值乘以50獲得了矩形高度的變化量。將變化量加在矩形的左上與右上兩個頂點的y座標上。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
//初始角度爲0
var
step = 0;
function
loop(){
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.fillStyle =
"rgba(0,222,255, 0.2)"
;
//角度增長一度
step++;
//角度轉換成弧度
var
angle = step*Math.PI/180;
//矩形高度的變化量
var
deltaHeight = Math.sin(angle) * 50;
ctx.beginPath();
//在矩形的左上與右上兩個頂點加上高度變化量
ctx.moveTo(0, canvas.height/2+deltaHeight);
ctx.lineTo(canvas.width, canvas.height/2+deltaHeight);
ctx.lineTo(canvas.width, canvas.height);
ctx.lineTo(0, canvas.height);
ctx.lineTo(0, canvas.height/2+deltaHeight);
ctx.closePath();
ctx.fill();
requestAnimFrame(loop);
}
|
運行代碼:
將右上頂點的變化值改成角度的餘弦,使其左右不一樣步。var deltaHeightRight = Math.cos(angle) * 50;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
//初始角度爲0
var
step = 0;
function
loop(){
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.fillStyle =
"rgba(0,222,255, 0.2)"
;
//角度增長一度
step++;
//角度轉換成弧度
var
angle = step*Math.PI/180;
//矩形高度的變化量
var
deltaHeight = Math.sin(angle) * 50;
//矩形高度的變化量(右上頂點)
var
deltaHeightRight = Math.cos(angle) * 50;
ctx.beginPath();
ctx.moveTo(0, canvas.height/2+deltaHeight);
//右上頂點
ctx.lineTo(canvas.width, canvas.height/2+deltaHeightRight);
ctx.lineTo(canvas.width, canvas.height);
ctx.lineTo(0, canvas.height);
ctx.lineTo(0, canvas.height/2+deltaHeight);
ctx.closePath();
ctx.fill();
requestAnimFrame(loop);
}
|
運行代碼:
Step4
將矩形的頂上的邊變成曲線。
在上面的代碼中咱們用lineTo來繪製矩形的邊,爲了要繪製曲線咱們須要
bezierCurveTo(cpX1, cpY1, cpX2, cpY2, x, y)
函數。繪製的起點是矩形的左上頂點,結束點爲右上頂點。bezierCurveTo函數的參數中(cpX1,cpY1)與(cpX2,cpY2)分別是起點與結束點的控制點,(x,y)爲結束點。咱們將兩個控制點的x值設定在畫布的正中心,y值在起始點與終點的y值上面減去50;(canvas.width /2, canvas.height/2+deltaHeight-50),(canvas.width / 2,canvas.height/2+deltaHeightRight-50),能夠根據效果調整。
1
2
3
4
5
6
7
8
9
|
ctx.beginPath();
ctx.moveTo(0, canvas.height/2+deltaHeight);
//ctx.lineTo(canvas.width, canvas.height/2+deltaHeightRight);
//畫曲線
ctx.bezierCurveTo(canvas.width /2, canvas.height/2+deltaHeight-50, canvas.width / 2, canvas.height/2+deltaHeightRight-50, canvas.width, canvas.height/2+deltaHeightRight);
ctx.lineTo(canvas.width, canvas.height);
ctx.lineTo(0, canvas.height);
ctx.lineTo(0, canvas.height/2+deltaHeight);
ctx.closePath();
|
運行代碼:
Step5
一個波浪畫好了。咱們只須要同時畫3個不一樣顏色的波浪,而且使不一樣波浪的角度不一樣就能夠獲得效果圖中的效果了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
//定義三條不一樣波浪的顏色
var
lines = [
"rgba(0,222,255, 0.2)"
,
"rgba(157,192,249, 0.2)"
,
"rgba(0,168,255, 0.2)"
];
function
loop(){
ctx.clearRect(0,0,canvas.width,canvas.height);
step++;
//畫3個不一樣顏色的矩形
for
(
var
j = lines.length - 1; j >= 0; j--) {
ctx.fillStyle = lines[j];
//每一個矩形的角度都不一樣,每一個之間相差45度
var
angle = (step+j*45)*Math.PI/180;
var
deltaHeight = Math.sin(angle) * 50;
var
deltaHeightRight = Math.cos(angle) * 50;
ctx.beginPath();
ctx.moveTo(0, canvas.height/2+deltaHeight);
ctx.bezierCurveTo(canvas.width /2, canvas.height/2+deltaHeight-50, canvas.width / 2, canvas.height/2+deltaHeightRight-50, canvas.width, canvas.height/2+deltaHeightRight);
ctx.lineTo(canvas.width, canvas.height);
ctx.lineTo(0, canvas.height);
ctx.lineTo(0, canvas.height/2+deltaHeight);
ctx.closePath();
ctx.fill();
}
requestAnimFrame(loop);
}
|
運行代碼:
Step6
添加好按鈕與logo的HTML代碼就大功告成了。