溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

用Canvas為網(wǎng)頁添加動態(tài)背景

發(fā)布時間:2020-07-10 12:21:40 來源:網(wǎng)絡 閱讀:7051 作者:cyclegtx 欄目:移動開發(fā)


最近剛剛接到為微信公眾帳號“玩轉三里屯”制作首頁的任務??紤]到頁面只在手機中瀏覽,而且手機對canvas的支持又非常好,所以打算使用canvas做點不一樣的動畫。

首先來看下效果圖。

用Canvas為網(wǎng)頁添加動態(tài)背景

要實現(xiàn)這樣的動畫普通的CSS3是鞭長莫及了,只能使用Canvas。好在使用canvas也非常簡單。

Step1.

新建一個畫布(<canvas>)元素,并放在在所有按鈕和logo的下方以免遮擋前面的元素。

<canvas id="canvas" ></canvas>

將Canvas的寬高設定成其父元素的寬高,以充滿他的父元素。也可以直接使用window.innerHeight,window.innerWidth。使其充滿整個屏幕。

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
canvas.width = canvas.parentNode.offsetWidth;
canvas.height = canvas.parentNode.offsetHeight;

Step2.


在畫布中畫一個充滿半個屏幕的矩形。

我們只需要找到矩形的四個定點的坐標,使用Canvas的繪制路徑并填充這個路徑。四個點分別是:

(0, 畫布高度t/2)
(畫布寬度, 畫布高度t/2)
(畫布寬度 畫布高度t/2)
(0, 畫布高度t/2)

注意:坐標的(0,0)在畫布的左上角。

//填充顏色
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();

運行代碼:

用Canvas為網(wǎng)頁添加動態(tài)背景

Step3.

讓矩形動起來。要做動畫我們需要持續(xù)的清空畫布并重新繪制新的矩形,就像電影每秒播放24張圖片。我們新建一個loop函數(shù),用來繪制每一幀的圖像,并使用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中,并在繪制矩形的代碼之前清空畫布中所有的圖形。

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);
}

接下來我們更改每一幀中的矩形的高度來模擬波浪的形態(tài),波浪其實是在波峰與波谷之間做周期性運動。我們假設波峰與波谷間都是50px,那么矩形的高度的變化值應該在-50px到50px之間。為了達到周期性的效果我們采用正弦函數(shù)sin(x),因為不管x值怎么變化sin(x)的值始終在-1與1之間。我們新建一個變量 var step =0 使其在每一幀中自增,表示每一幀角度增加一度,并用Math.sin()取他的正弦值。JS中的sin使用的弧度值,我們需要把step轉換成弧度值,var angle = step*Math.PI/180; 取角度的正弦值乘以50得到了矩形高度的變化量。將變化量加在矩形的左上與右上兩個頂點的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);
}

運行代碼:

用Canvas為網(wǎng)頁添加動態(tài)背景

將右上頂點的變化值改為角度的余弦,使其左右不同步。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);
}

運行代碼:

用Canvas為網(wǎng)頁添加動態(tài)背景

Step4

將矩形的頂上的邊變成曲線。

在上面的代碼中我們用lineTo來繪制矩形的邊,為了要繪制曲線我們需要

bezierCurveTo(cpX1, cpY1, cpX2, cpY2, x, y)

函數(shù)。繪制的起點是矩形的左上頂點,結束點為右上頂點。bezierCurveTo函數(shù)的參數(shù)中(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),可以根據(jù)效果調整。

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();

運行代碼:

用Canvas為網(wǎng)頁添加動態(tài)背景

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);
}

運行代碼:

用Canvas為網(wǎng)頁添加動態(tài)背景

Step6

添加好按鈕與logo的HTML代碼就大功告成了。

用Canvas為網(wǎng)頁添加動態(tài)背景

查看所有代碼請去Github

如有問題或者建議請微博@UED天機。我會及時回復

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。

AI