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

来源:http://www.cnblogs.com/tangyifeng/archive/2016/03/08/5253629.html
-Advertisement-
Play Games

看到網上很多展示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),沒有功勞也有苦勞啊,大家都給我評論下嘛

 

以後還有更多喲,請大家一起來交流下。

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在當今時代,SVG是最流行的和正在被眾多的設計人員和開發人員使用,創建支持視網膜和響應式的網頁設計。繪製SVG不是一個艱巨的任務,因為大量的 JavaScript 庫可與 SVG 圖像搭配使用。這些JS庫幫助設計師和開發人員可以輕鬆地為他們的項目和Web應用程式創建創新和逼真的圖形。 1.Textu
  • 回到目錄 在bootstrap官方來說,導航最多就是兩級,兩級以上是無法實現的,大叔找了一些第三方的資料,終於找到一個不錯的插件,使用上和效果上都還不錯,現在和大家分享一下 插件地址:http://vsn4ik.github.io/bootstrap-submenu/ 先看一下,在大叔後臺系統上的顯
  • 本示例使用HTML5的canvas標簽和Javascript腳本,簡單的編寫了裝載圖片效果, 請使用支持HTML5的瀏覽器預覽效果: 下圖為以逐漸橫向柵格的效果圖 html部分: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8
  • 介紹vw、vh,然後對三篇文章做一個總結。屏幕適配是一個很容易被忽略的問題,但對於精益求精的產品而言,是必不可少的。對於Web開發的求職者而言,也是一個必需要理解清楚的經典問題
  • 回到占占推薦博客索引 bootstrap已經用了有段時間了,感覺在使用上還是比較容易接受的,在開發人員用起來上,也還好,不用考慮它的相容性,手機,平臺,PC都可以有效的相容。 bootstrap官方api:http://v3.bootcss.com/ Bootstrap~學習筆記索引 Bootstr
  • 一:需求分析 1)需要首頁,末頁功能 2)有點擊查看上一頁,下一頁功能 3)頁碼到當前可視頁碼最後一頁刷新頁面 二:功能實現思路 也是分為三部分處理 1)點擊首頁,末頁直接顯示第一頁或者最後一頁內容,當前頁面為第1頁或者最後一頁。隱藏首頁或者末頁按鈕。demo 顯示截圖 首頁狀態 和 末頁狀態代碼執
  • HTML 教程 HTML 簡介 html div 標簽介紹 html span 標簽介紹 html a 超鏈接標簽 HTML Br換行標簽介紹 HTML P段落標簽介紹 HTML br與p標簽區別 Html H 標題標簽 html px em pt長度單位 HTML B 加粗標簽 HTML stro
  • 在很多現實的場景中,有的文本框我們希望在選擇“是”的按鈕之後才出現,這就需要js控制TR的隱藏和顯示,如何控制,本文為大家揭曉 下文分享的一段代碼:選擇是的按鈕就顯示身高和體重的文本框的代碼。註意:ready方法必須要引用jquery的庫。 1.html Code <html> <head> <me
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...