首页 > web前端 > html教程 > html5实现下雪效果的方法

html5实现下雪效果的方法

一个新手
发布: 2018-05-17 16:14:23
原创
8895 人浏览过

利用canvas,实现一个下雪的效果,我们先预览下效果:

我们先分析下这个效果:

1,随机产生雪花

2,雪花的产生不是同时产生,而是有先后顺序的

3,雪花怎么表示

4,怎么源源不断的下雪

5,雪花有大有小

搞清楚上面几个问题之后,这个效果基本上就实现了,

首先,由于这个是全屏效果,我采用动态创建canvas,把整个浏览器的宽与高赋值给canvas

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

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,宽、高与浏览器的宽、高相同,背景为黑色,晚上下雪的效果

接下来,有了舞台,演员该上场了,怎么产生雪花呢?这里把下雪相关的操作,封装成一个类,他的基本结构如下:

1

2

3

4

5

6

var Snow = function(){}

Snow.prototype = {

  init : function(){},

  draw : function( cxt ) {},

  update : function(){}

}

登录后复制

这个类一共有三个方法( init, draw, update ).

init:初始化雪花的位置( x, y 坐标 )、速度、半径( 雪花的大小,在这里我们把雪花用半径不同的圆表示 )

1

2

3

4

5

6

7

8

9

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方法,绘制雪花:

1

2

3

4

5

6

7

8

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方法,他是干嘛的?他是更新雪花在垂直方向的速度

1

2

3

4

5

6

7

update: function (cxt) {

                    if (this.y < height - this.r) {

                        this.y += this.vy;

                    } else {

                        this.init();

                    }

                }

登录后复制

在update方法中,我们做了边界判断: 雪花往下飘落的时候,肯定会消失,消失之后怎么处理?没有到达边界怎么处理?

canvas的高度减去雪花的半径,这就是雪花要消失时候的边界,所以this.y < height - this.r 如果这个条件成立,那么说明雪花一直在飘着,我们就要把雪花的y方向的位置更新,雪花看起来(‘正在下雪’),当一个雪花快要消失的时候,我们再把他移动到初始的位置,这样看起来就是在圆圆不断的下雪,而不需要重新绘制雪花(如果这样做,肯定会影响性能,这个特效最后肯定会被卡死,这个小技巧很多类似的特效都会用到)。至此核心的流程已经搞定,接下来,我们就要大量的生成雪花了。

1

2

3

4

5

6

7

8

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实战进度条

1

2

3

4

5

6

7

(function move() {

                oGc.clearRect(0, 0, width, height);

                for (var i = 0; i < snow.length; i++) {

                    snow[i].draw(oGc);

                }

                requestAnimationFrame(move);

            })();

登录后复制

完整的demo代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

<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>

 

 

 

<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
最新问题
HTML与HTML5的区别
来自于 1970-01-01 08:00:00
0
0
0
symfony 2.1 的 html5 校验
来自于 1970-01-01 08:00:00
0
0
0
能不能用html5做一个图片滚动效果
来自于 1970-01-01 08:00:00
0
0
0
javascript - html5显示隐藏
来自于 1970-01-01 08:00:00
0
0
0
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板