看到網上很多展示html5雪花飛動的效果,確實非常引人入勝,我相信大家也跟我一樣看著心動的同時,也很好奇,想研究下代碼如何實現;雖然哦很多地方也能下載這些源碼,不過也不知道別人製作此類動畫時的思路及難點分析。 我這幾天剛好學習了一下,也趁著此刻有時間從需求分析、知識點、程式編寫一步步給大家解剖下。
看到網上很多展示html5雪花飛動的效果,確實非常引人入勝,我相信大家也跟我一樣看著心動的同時,也很好奇,想研究下代碼如何實現;雖然哦很多地方也能下載這些源碼,不過也不知道別人製作此類動畫時的思路及難點分析。
我這幾天剛好學習了一下,也趁著此刻有時間從需求分析、知識點、程式編寫一步步給大家解剖下,要是在各位關公面前耍大刀了,可別見笑喲。
最終效果圖如下:
圖1
一、需求分析
1、圓形雪花
本示例中雪花形狀使用圓形
2、雪花數量固定
根據圖1仔細觀察白色雪花數量,飄落過程中,整張圖的雪花數量應該是固定的,這個需求是需要通過我們觀察分析所得。這與我們現實生活中看到一幅雪花滿天飛的場景是一致的。
3、雪花大小不一致
每朵雪花它們大小各有不同,也就意味著雪花的半徑是隨機的。這與我們現實生活中看到一幅雪花滿天飛的場景也是一致的。
4、雪花位置在移動
雪花飄落,自然它們的位置也在移動。
二、知識點
1、使用Html5 Canvas+JavaScript畫圓——構成圓形雪花
在Html5中,需要使用Canvas同時藉助JavaScript畫圓,以構成圓形雪花——arc(x,y,r,start,stop);
2、隨機數—產生不同半徑、坐標的圓形雪花
本示例中,網頁第一次載入時,需要生成一定數量的不同半徑及位置的雪花,故半徑、坐標為隨機數;雪花在飄落過程中,其半徑不變,坐標在一定幅度內變化,故此時坐標也為隨機數——Math.random()
三、程式編寫
1、準備工作
放一個畫布canvas,並且設置整個body背景色為黑色
HTML代碼:
<canvas id="mycanvas">
您的瀏覽器不支持canvas畫布
</canvas>
CSS代碼:
* {
margin: 0;
padding: 0;
}
#mycanvas {
background: black;
}
此時效果如如下:
註意:canvas預設是有一個初始化高度和寬度的,所以不用去糾結
2、畫佈滿屏顯示
JavaScript代碼如下:
//獲取mycanvas畫布
var can = document.getElementById("mycanvas");
var ctx = can.getContext("2d");
//畫布寬度
var wid = window.innerWidth;
//畫布高度
var hei = window.innerHeight;
can.width=wid;
can.height=hei;
此時效果如如下:
3、初始化生成固定數量的雪花
根據我們上述需求分析及知識點解讀,首先雪花的數量是固定的,所以我們需要定義一個變數var snow = 100;這裡假設雪花數量為100,;
生成雪花的時候,每個雪花半徑、位置都不同,我們把每個雪花當做一個對象,那麼這個對象的屬性就包含:半徑、坐標(X、Y),那麼一個雪花對象可以寫成var snowOject={x:1,y:10,r:5},這裡就代表一個坐標為(1,10)半徑為5的圓形雪花;本示例中由於半徑和坐標都為隨機數,故使用Math.random()分別為100個雪花生成半徑、坐標(X、Y);
那我們這裡是100個雪花,所以為了方便後面操作,就用一個數組保存這100個雪花對象。
JavaScript代碼如下:
//雪花數目
var snow = 100;
//雪花坐標、半徑
var arr = []; //保存各圓坐標及半徑
for (var i = 0; i < snow; i++) {
arr.push({
x: Math.random() * wid,
y: Math.random() * hei,
r: Math.random() * 10 + 1
})
}
4、繪製雪花
上面我們已經將100個雪花半徑、坐標(X、Y)生成,下麵就是迴圈使用canvas畫出雪花了(這裡就是畫圓),這裡定義一個函數
JavaScript代碼如下:
//畫雪花
function DrawSnow() {
ctx.fillStyle="white";
ctx.beginPath();
for (var i = 0; i < snow; i++) {
var p = arr[i];
ctx.moveTo(p.x,p.y);
ctx.arc(p.x,p.y,p.r,0,2*Math.PI,false);
}
ctx.fill();
ctx.closePath();
然後調用 DrawSnow()函數,效果如下:
可以嘗試多次刷新網頁看是否會生成不同大小、位置的雪花(正常情況下是可以的),做到這裡就已經接近最終效果了
註意:由於這裡需要繪製100個圓,所以每當畫一個圓時重新定義繪製開始坐標即:ctx.moveTo(p.x,p.y);否則會出現異樣效果,不信可以試試呀
5、雪花飄動
上面我們已經畫出100個雪花,可惜只能依靠刷新網頁才能看到變化效果,但是我們需要實現的是雪花不停的移動位置。
首先我們需要藉助setInterval函數不停的重畫雪花,這裡間隔時間為50毫秒:setInterval(DrawSnow,50);
同時每一朵雪花的坐標(X、Y)需要不停的改變(在一定幅度內),我們這裡的雪花是從左上方飄落到右下方,所以每朵X、Y坐標值都在不停的增大,那我們用一個函數SnowFall()定義雪花飄過規則
該函數代碼如下:
//雪花飄落
function SnowFall() {
for (var i = 0; i < snow; i++) {
var p = arr[i];
p.y += Math.random() * 2 + 1;
if (p.y > hei) {
p.y = 0;
}
p.x += Math.random() * 2 + 1;
if (p.x > wid) {
p.x = 0;
<span style="white-space:pre"> </span>}
}
}
然後將該函數放入DrawSnow()執行,註意:我們每隔50毫毛重畫雪花,必須擦除畫布,所以DrawSnow()函數體內必須在前面執行clearRect()函數,即:ctx.clearRect(0, 0, wid, hei);
此時DrawSnow函數定義如下:
//畫雪花
function DrawSnow() {
ctx.clearRect(0, 0, wid, hei);
ctx.fillStyle = "white";
ctx.beginPath();
for (var i = 0; i < snow; i++) {
var p = arr[i];
ctx.moveTo(p.x, p.y);
ctx.arc(p.x, p.y, p.r, 0, 2 * Math.PI, false);
}
ctx.fill();
SnowFall();
ctx.closePath();
}
最後執行setInterval(DrawSnow, 50);
OK,經過我們上述步驟,小伙伴們是否已經對整個過程及技術實現很清晰了。
完整代碼如下(大家可以直接複製到自己項目中執行,測試下效果):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="js/jquery-1.8.3.min.js"></script>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
#mycanvas {
background: black;
}
</style>
</head>
<body>
<canvas id="mycanvas">
您的瀏覽器不支持canvas畫布
</canvas>
<script>
//獲取mycanvas畫布
var can = document.getElementById("mycanvas");
var ctx = can.getContext("2d");
//畫布寬度
var wid = window.innerWidth;
//畫布高度
var hei = window.innerHeight;
can.width = wid;
can.height = hei;
//雪花數目
var snow = 100;
//雪花坐標、半徑
var arr = []; //保存各圓坐標及半徑
for (var i = 0; i < snow; i++) {
arr.push({
x: Math.random() * wid,
y: Math.random() * hei,
r: Math.random() * 10 + 1
})
}
//畫雪花
function DrawSnow() {
ctx.clearRect(0, 0, wid, hei);
ctx.fillStyle = "white";
ctx.beginPath();
for (var i = 0; i < snow; i++) {
var p = arr[i];
ctx.moveTo(p.x, p.y);
ctx.arc(p.x, p.y, p.r, 0, 2 * Math.PI, false);
}
ctx.fill();
SnowFall();
ctx.closePath();
}
//雪花飄落
function SnowFall() {
for (var i = 0; i < snow; i++) {
var p = arr[i];
p.y += Math.random() * 2 + 1;
if (p.y > hei) {
p.y = 0;
}
p.x += Math.random() * 2 + 1;
if (p.x > wid) {
p.x = 0;
}
}
}
setInterval(DrawSnow, 50);
</script>
</body>
</html>
好了,今天分享就到這裡,我現在都寫到半夜了喲(此刻:2016年3月8日00:22:27),沒有功勞也有苦勞啊,大家都給我評論下嘛
以後還有更多喲,請大家一起來交流下。