1. 程式人生 > >canvas實現雪花效果

canvas實現雪花效果

        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. 效果: