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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...