HTML5 canvas繪製雪花飄落動畫(需求分析、知識點、程序編寫分佈詳解)

看到網上不少展現html5雪花飛動的效果,確實很是引人入勝,我相信你們也跟我同樣看着心動的同時,也很好奇,想研究下代碼如何實現;雖然哦不少地方也能下載這些源碼,不過也不知作別人制做此類動畫時的思路及難點分析。css

我這幾天恰好學習了一下,也趁着此刻有時間從需求分析、知識點、程序編寫一步步給你們解剖下,要是在各位關公面前耍大刀了,可別見笑喲。html

最終效果圖以下:html5

圖1jquery

1、需求分析canvas

一、圓形雪花數組

本示例中雪花形狀使用圓形瀏覽器

二、雪花數量固定dom

根據圖1仔細觀察白色雪花數量,飄落過程當中,整張圖的雪花數量應該是固定的,這個需求是須要經過咱們觀察分析所得。這與咱們現實生活中看到一幅雪花滿天飛的場景是一致的。函數

三、雪花大小不一致學習

每朵雪花它們大小各有不一樣,也就意味着雪花的半徑是隨機的。這與咱們現實生活中看到一幅雪花滿天飛的場景也是一致的。

四、雪花位置在移動

雪花飄落,天然它們的位置也在移動。

 

2、知識點

一、使用Html5 Canvas+JavaScript畫圓——構成圓形雪花

在Html5中,須要使用Canvas同時藉助JavaScript畫圓,以構成圓形雪花——arc(x,y,r,start,stop);

二、隨機數—產生不一樣半徑、座標的圓形雪花

本示例中,網頁第一次加載時,須要生成必定數量的不一樣半徑及位置的雪花,故半徑、座標爲隨機數;雪花在飄落過程當中,其半徑不變,座標在必定幅度內變化,故此時座標也爲隨機數——Math.random()

 

3、程序編寫

一、準備工做

放一個畫布canvas,而且設置整個body背景色爲黑色

HTML代碼:

<canvas id="mycanvas"> 您的瀏覽器不支持canvas畫布 </canvas>

 


CSS代碼:

* { margin: 0; padding: 0;
} #mycanvas { background: black;
}

 

此時效果如以下:

注意:canvas默認是有一個初始化高度和寬度的,因此不用去糾結

二、畫布滿屏顯示

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;

 

此時效果如以下:

三、初始化生成固定數量的雪花

根據咱們上述需求分析及知識點解讀,首先雪花的數量是固定的,因此咱們須要定義一個變量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 }) }

 

四、繪製雪花

上面咱們已經將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);不然會出現異樣效果,不信能夠試試呀

 五、雪花飄動

上面咱們已經畫出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),沒有功勞也有苦勞啊,你們都給我評論下嘛

 

之後還有更多喲,請你們一塊兒來交流下。

相關文章
相關標籤/搜索