溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

html5如何實(shí)現(xiàn)下雪效果

發(fā)布時(shí)間:2021-02-24 14:16:23 來(lái)源:億速云 閱讀:329 作者:小新 欄目:web開(kāi)發(fā)

這篇文章主要介紹html5如何實(shí)現(xiàn)下雪效果,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!

利用canvas,實(shí)現(xiàn)一個(gè)下雪的效果,我們先預(yù)覽下效果:

我們先分析下這個(gè)效果:

1,隨機(jī)產(chǎn)生雪花

2,雪花的產(chǎn)生不是同時(shí)產(chǎn)生,而是有先后順序的

3,雪花怎么表示

4,怎么源源不斷的下雪

5,雪花有大有小

搞清楚上面幾個(gè)問(wèn)題之后,這個(gè)效果基本上就實(shí)現(xiàn)了,

首先,由于這個(gè)是全屏效果,我采用動(dòng)態(tài)創(chuàng)建canvas,把整個(gè)瀏覽器的寬與高賦值給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();

調(diào)用oCanvas對(duì)象的init方法之后,就會(huì)在body的最后面追加一個(gè)canvas,id為canvas,寬、高與瀏覽器的寬、高相同,背景為黑色,晚上下雪的效果

接下來(lái),有了舞臺(tái),演員該上場(chǎng)了,怎么產(chǎn)生雪花呢?這里把下雪相關(guān)的操作,封裝成一個(gè)類(lèi),他的基本結(jié)構(gòu)如下:

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

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

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

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 加上 這個(gè)random函數(shù) 就可以完成雪花的初始化

1,雪花出來(lái)的時(shí)候,一般是在屏幕的最上方出現(xiàn)的,所以雪花的y坐標(biāo)都是0,  其次,雪花的x坐標(biāo)是隨機(jī)的,他的范圍是從屏幕的左邊到右邊,那么就是 0 ~ width. 這個(gè)width就是canvas的寬度,也就是瀏覽器的寬度

2,雪花的半徑r, 設(shè)置為1 ~ 5之間的任意值

3,雪花下降的速度設(shè)置為3 ~ 5之間的隨機(jī)速度,這里我做的下雪是垂直方向往下飄,你可以拓展,考慮風(fēng)力影響( 這個(gè)時(shí)候肯定有水平方向的速度 )

有了這些初始化的參數(shù)之后,我們完善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);
                },

參數(shù)cxt就是canvas的上下文,這個(gè)函數(shù)很簡(jiǎn)單,就是一個(gè)arc方法調(diào)用init中設(shè)置的值來(lái)畫(huà)圓(雪花),在該方法的最后調(diào)用了一個(gè)update方法,他是干嘛的?他是更新雪花在垂直方向的速度

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

在update方法中,我們做了邊界判斷: 雪花往下飄落的時(shí)候,肯定會(huì)消失,消失之后怎么處理?沒(méi)有到達(dá)邊界怎么處理?

canvas的高度減去雪花的半徑,這就是雪花要消失時(shí)候的邊界,所以this.y  < height - this.r  如果這個(gè)條件成立,那么說(shuō)明雪花一直在飄著,我們就要把雪花的y方向的位置更新,雪花看起來(lái)(‘正在下雪’),當(dāng)一個(gè)雪花快要消失的時(shí)候,我們?cè)侔阉苿?dòng)到初始的位置,這樣看起來(lái)就是在圓圓不斷的下雪,而不需要重新繪制雪花(如果這樣做,肯定會(huì)影響性能,這個(gè)特效最后肯定會(huì)被卡死,這個(gè)小技巧很多類(lèi)似的特效都會(huì)用到)。至此核心的流程已經(jīng)搞定,接下來(lái),我們就要大量的生成雪花了。

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

生成500個(gè)雪花,不是同時(shí)生成的,然后把這些雪花保存到數(shù)組snow中.

然后,開(kāi)啟定時(shí)器,讓雪花不斷的飄落吧,

關(guān)于requestAnimationFrame的使用,可以參考我的這篇文章:[js高手之路] html5新增的定時(shí)器requestAnimationFrame實(shí)戰(zhàn)進(jìn)度條

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

完整的demo代碼:

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>雪花效果 - by ghostwu</title>
    <!-- <script src="lib.js"></script> -->
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        body {
            overflow: hidden;
        }
    </style>
</head>

<body>
    <script>
        window.onload = function () {
            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();

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

            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 = 'white';
                    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 < height - this.r) {
                        this.y += this.vy;
                    } else {
                        this.init();
                    }
                }
            }

            var snow = [];
            for (var i = 0; i < 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 < snow.length; i++) {
                    snow[i].draw(oGc);
                }
                requestAnimationFrame(move);
            })();
        }
    </script>
</body>

以上是“html5如何實(shí)現(xiàn)下雪效果”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI