近期剛剛接到為微信公眾帳號“玩轉三里屯”制作首頁的任務。
考慮到頁面僅僅在手機中瀏覽。並且手機對canvas的支持又很好,所以打算使用canvas做點不一樣的動畫。
首先來看下效果圖。
要實現這種動畫普通的CSS3是鞭長莫及了,僅僅能使用Canvas。好在使用canvas也很easy。
Step1.
新建一個畫布(<canvas>)元素,並放在在全部button和logo的下方以免遮擋前面的元素。
<canvas id="canvas" style="position:absolute;top:0px;left:0px;z-index:1;"></canvas>
將Canvas的寬高設定成其父元素的寬高,以充滿他的父元素。也能夠直接使用 window.innerHeight,window.innerWidth。使其充滿整個屏幕。
在畫布中畫一個充滿半個屏幕的矩形。
我們僅僅須要找到矩形的四個定點的坐標,使用Canvas的繪制路徑並填充這個路徑。
四個點各自是:
(0, 畫布高度t/2)
(畫布寬度, 畫布高度t/2)
(畫布寬度 畫布高度t/2)
(0, 畫布高度t/2)
注意:坐標的(0,0)在畫布的左上角。
執行代碼:
Step3.
讓矩形動起來。
要做動畫我們須要持續的清空畫布並又一次繪制新的矩形。就像電影每秒播放24張圖片。我們新建一個loop函數,用來繪制每一幀的圖像,並使用requestAnimFrame來告訴瀏覽器每一幀都要使用loop來繪制。
//假設瀏覽器支持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中。並在繪制矩形的代碼之前清空畫布中全部的圖形。
將變化量加在矩形的左上與右上兩個頂點的y坐標上。
//初始角度為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;
//初始角度為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),能夠依據效果調整。
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.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個不同顏色的波浪,而且使不同波浪的角度不同就能夠得到效果圖中的效果了。
//定義三條不同波浪的顏色 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
加入好button與logo的HTML代碼就大功告成了。
如有問題或者建議請微博@UED天機。
我會及時回復
也能夠收藏天機的官網,http://ued.sexy/ 常常更新最新的教程。
======
相關閱讀