canvas实现雪花效果

时间:2022-12-21 21:11:14
        function SnowAnimate(config){
            this.defaultConfig = {
                canvasId:'mycanvas',//canvas id
                snowCount:200,//雪花数
                radius:4,//半径
                intervalTime:40//毫秒
            };
            this.config = $.extend(this.defaultConfig,config);
            var that = this;
        //获取mycanvas画布
            var can = document.getElementById(this.config.canvasId);
            var ctx = can.getContext("2d");
            //画布宽度
            var wid = $(document).width();
            //画布高度
            var hei = $(document).height();

            //两张雪花图片

   var snowImage = document.getElementById('snow_1');   

            var snowImage2 = document.getElementById('snow_2'); 

            var counter = 0;


            can.width = wid;
            can.height = hei;
            //雪花数目
            var snow = this.config.snowCount;
            //雪花坐标、半径
            var arr = []; //保存各圆坐标及半径


              for (var i = 0; i < snow; i++) {
                arr.push({
                    x: Math.random() * wid,
                    y: Math.random() * hei,
                    r: Math.random() * that.config.radius + 1,
                    snowType:0
                })
            }

             //画雪花
            this.DrawSnow = function() {
                counter++;
                ctx.clearRect(0, 0, wid, hei);
                ctx.beginPath();
                for (var i = 0; i < snow; i++) {
                    var p = arr[i];
                    var snow_image = (p.snowType == 0)?snowImage:snowImage2;
                    if(counter % 3 == 0){  //每3张切换一次图片
                       p.snowType = 1 - p.snowType;
                    }
                    ctx.drawImage(snow_image, p.x, p.y, p.r*2, p.r*2);
                }
                ctx.fill();
                that.SnowFall();
                ctx.closePath();
            }
            //雪花飘落
            this.SnowFall =function() {
                for (var i = 0; i < snow; i++) {
                    var p = arr[i];
                    p.y += Math.random() * 1 + 2;
                    if (p.y > hei) {
                        p.y = 0;
                    }
                    p.x += Math.random() * 1 + 1;
                    if (p.x > wid) {
                        p.x = 0;
                    }
                }
            }
            this.run = function(){
                setInterval(that.DrawSnow, that.config.intervalTime);
            }


        }


备注:

1.  使用两张图片是因为一开始使用gif图片时intervalTime只有几十毫秒,还没看出动画效果,就已经重新绘制图片,导致动画效果不明显,尺寸小的图会有明显的抖动,类似旋转雪花,尺寸大的雪花图基本看不出动画,所以采用两张图片来解决这个问题。每3帧切换一次图片,能够比较流畅的看到动画效果。两张雪花图类似 + 和x 的形状,

2. 两种方法获取图片:

第一种图片方式:

html

<img src="$imagePrefix/201612_snowflower_pc/snow_1.png" id="snow_1" alt="">
<img src="$imagePrefix/201612_snowflower_pc/snow_2.png" id="snow_2" alt="">

js

            var snowImage = document.getElementById('snow_1');   

            var snowImage2 = document.getElementById('snow_2'); 

种图片方式:

    var snowImage = new Image();

    snowImage.src = 'address1'

    var snowImage2 = new Image();

    snowImage.src = 'address2'

3. 使用

通过二次调用来调节远近疏密能获得比较好的效果。

new SnowAnimate( {
                canvasId:'mycanvas',//canvas id
                snowCount:400,//雪花数
                radius:4,//半径
                intervalTime:60
         }).run();
new SnowAnimate( {
                canvasId:'mycanvas2',//canvas id
                snowCount:200,//雪花数
                radius:12,//半径
                intervalTime:40
         }).run();


4. 效果:

canvas实现雪花效果