首頁  >  文章  >  web前端  >  html5實現下雪效果的方法

html5實現下雪效果的方法

一个新手
一个新手原創
2018-05-17 16:14:238746瀏覽

利用canvas,實現一個下雪的效果,我們先預覽下效果:

我們先分析下這個效果:

1,隨機產生雪花

2 ,雪花的產生不是同時產生,而是有先後順序的

3,雪花怎麼表示

4,怎麼源源不絕的下雪

5,雪花有大有小

搞清楚上面幾個問題之後,這個效果基本上就實現了,

#首先,由於這個是全屏效果,我採用動態創建canvas,把整個瀏覽器的寬與高賦值給canvas

var Canvas = function (w, h) {
                this.width = w;
                this.height = h;
            }
            Canvas.prototype = {
                init: function () {
                    var oC = document.createElement("canvas");
                    oC.setAttribute('width', this.width);
                    oC.setAttribute('height', this.height);
                    oC.setAttribute('id', 'canvas');
                    oC.style.backgroundColor = '#000';
                    document.body.appendChild(oC);
                }
            }
            var curWinWidth = window.innerWidth,
                curWinHeight = window.innerHeight;
            var oCanvas = new Canvas(curWinWidth, curWinHeight);
            oCanvas.init();

呼叫oCanvas物件的init方法之後,就會在body的最後面追加一個canvas,id為canvas,寬、高與瀏覽器的寬、高相同,背景為黑色,晚上下雪的效果

接下來,有了舞台,演員該上場了,怎麼產生雪花呢?這裡把下雪相關的操作,封裝成一個類,他的基本結構如下:

var Snow = function(){}
Snow.prototype = {
  init : function(){},
  draw : function( cxt ) {},
  update : function(){}
}

這個類一共有三個方法( init, draw, update ).

init:初始化雪花的位置( x, y 座標)、速度、半徑( 雪花的大小,在這裡我們把雪花用半徑不同的圓表示)

function random(min, max) {
                return Math.random() * (max - min) + min;
            }
            init: function () {
                    this.x = random(0, width);
                    this.y = 0;
                    this.r = random(1, 5);
                    this.vy = random(3, 5);
                }

那麼init 加上這個random函數就可以完成雪花的初始化

1,雪花出來的時候,通常是在螢幕的最上方出現的,所以雪花的y座標都是0,  其次,雪花的x座標是隨機的,他的範圍是從螢幕的左邊到右邊,那就是0 ~ width. 這個width就是canvas的寬度,也就是瀏覽器的寬度

2,雪花的半徑r, 設定為1 ~ 5之間的任意值

3,雪花下降的速度設定為3 ~ 5之間的隨機速度,這裡我做的下雪是垂直方嚮往下飄,你可以拓展,考慮風力影響( 這個時候肯定有水平方向的速度)

有了這些初始化的參數之後,我們完善draw方法,繪製雪花:

draw: function (cxt) {
                    cxt.beginPath();
                    cxt.fillStyle = 'white';
                    cxt.arc(this.x, this.y + this.r, this.r, 0, Math.PI * 2, false);
                    cxt.fill();
                    cxt.closePath();
                    this.update(cxt);
                },

參數cxt就是canvas的上下文,這個函數很簡單,就是一個arc方法呼叫init中設定的值來畫圓(雪花),在該方法的最後調用了一個update方法,他是乾嘛的?他是更新雪花在垂直方向的速度

update: function (cxt) {
                    if (this.y < height - this.r) {
                        this.y += this.vy;
                    } else {
                        this.init();
                    }
                }

在update方法中,我們做了邊界判斷: 雪花往下飄落的時候,一定會消失,消失之後怎麼處理?沒有到達邊界怎麼處理?

canvas的高度減去雪花的半徑,這就是雪花要消失時候的邊界,所以this.y  < height - this.r  如果這個條件成立,那麼說明雪花一直在飄著,我們就要把雪花的y方向的位置更新,雪花看起來('正在下雪'),當一個雪花快要消失的時候,我們再把他移動到初始的位置,這樣看起來就是在圓圓不斷的下雪,而不需要重新繪製雪花(如果這樣做,肯定會影響性能,這個特效最後肯定會被卡死,這個小技巧很多類似的特效都會用到)。至此核心的流程已經搞定,接下來,我們就要大量的生成雪花了。

var snow = [];
            for (var i = 0; i < 500; i++) {
                setTimeout(function () {
                    var oSnow = new Snow();
                    oSnow.init();
                    snow.push(oSnow);
                }, 10 * i);
            }

產生500個雪花,不是同時產生的,然後把這些雪花保存到數組snow中.

然後,開啟定時器,讓雪花不斷的飄落吧,

關於requestAnimationFrame的使用,可以參考我的這篇文章:[js高手之路] html5新增的定時器requestAnimationFrame實戰進度條

(function move() {
                oGc.clearRect(0, 0, width, height);
                for (var i = 0; i < snow.length; i++) {
                    snow[i].draw(oGc);
                }
                requestAnimationFrame(move);
            })();

完整的demo程式碼:


    
    
    
    雪花效果 - by ghostwu
    
    



    <script>
        window.onload = function () {
            var Canvas = function (w, h) {
                this.width = w;
                this.height = h;
            }
            Canvas.prototype = {
                init: function () {
                    var oC = document.createElement(&quot;canvas&quot;);
                    oC.setAttribute(&amp;#39;width&amp;#39;, this.width);
                    oC.setAttribute(&amp;#39;height&amp;#39;, this.height);
                    oC.setAttribute(&amp;#39;id&amp;#39;, &amp;#39;canvas&amp;#39;);
                    oC.style.backgroundColor = &amp;#39;#000&amp;#39;;
                    document.body.appendChild(oC);
                }
            }
            var curWinWidth = window.innerWidth,
                curWinHeight = window.innerHeight;
            var oCanvas = new Canvas(curWinWidth, curWinHeight);
            oCanvas.init();

            var oC = document.querySelector(&#39;#canvas&#39;);
            var width = oC.width, height = oC.height, oGc = oC.getContext(&#39;2d&#39;);

            function random(min, max) {
                return Math.random() * (max - min) + min;
            }
            var Snow = function () {

            }
            Snow.prototype = {
                init: function () {
                    this.x = random(0, width);
                    this.y = 0;
                    this.r = random(1, 5);
                    this.vy = random(3, 5);
                },
                draw: function (cxt) {
                    cxt.beginPath();
                    cxt.fillStyle = &amp;#39;white&amp;#39;;
                    cxt.arc(this.x, this.y + this.r, this.r, 0, Math.PI * 2, false);
                    cxt.fill();
                    cxt.closePath();
                    this.update(cxt);
                },
                update: function (cxt) {
                    if (this.y &lt; height - this.r) {
                        this.y += this.vy;
                    } else {
                        this.init();
                    }
                }
            }

            var snow = [];
            for (var i = 0; i &lt; 500; i++) {
                setTimeout(function () {
                    var oSnow = new Snow();
                    oSnow.init();
                    snow.push(oSnow);
                }, 10 * i);
            }

            (function move() {
                oGc.clearRect(0, 0, width, height);
                for (var i = 0; i &lt; snow.length; i++) {
                    snow[i].draw(oGc);
                }
                requestAnimationFrame(move);
            })();
        }
    </script>

以上是html5實現下雪效果的方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn