首页 > 代码库 > canvas下雪效果

canvas下雪效果

Demo: http://7li.github.io/h5/snow.html

<!DOCTYPE html> 
<html> 
<head> 
<style type="text/css"> 
body { 
background-color: #0c91b8; 
} 
</style> 
</head> 
<body > 
<script type="text/javascript">
	// Cross-browser-compliant
    requestAnimationFrame = window.requestAnimationFrame ||
                            window.mozRequestAnimationFrame ||
                            window.webkitRequestAnimationFrame ||
                            window.msRequestAnimationFrame || 
                            window.oRequestAnimationFrame ||
                            function(callback) { setTimeout(callback, 1000 / 60); };

    /**
     * Snow Class
     * @param {int}   x      
     * @param {int}   y      
     * @param {int}   radius 
     * @param {Function} fn     Formular to calculate x pos and y pos
     */
    function Snow (x, y, radius, fn) {
    	this.x = x;
    	this.y = y;
    	this.r = radius;
    	this.fn = fn;
    }
    Snow.prototype.update = function () {
    	this.x = this.fn.x (this.x, this.y);
    	this.y = this.fn.y (this.y, this.y);

    	if (this.x > window.innerWidth ||
    		this.x < 0 ||
    		this.y > window.innerHeight ||
    		this.y < 0 
    	){
    		this.x = getRandom('x');
    		this.y = 0;
    	}
    }
    Snow.prototype.draw = function (cxt) {
    	var grd = cxt.createRadialGradient (this.x, this.y, 0, this.x, this.y, this.r);
	    grd.addColorStop(0, "rgba(255, 255, 255, 0.9)");
		grd.addColorStop(.5, "rgba(255, 255, 255, 0.5)");
		grd.addColorStop(1, "rgba(255, 255, 255, 0)");
	    cxt.fillStyle = grd;
		cxt.fillRect (this.x - this.r, this.y - this.r, this.r * 2, this.r * 2);
    }

    /**
     * Snowlist class
     * Container to hold snow objects
     */	
    SnowList = function () {
    	this.list = [];
    }
    SnowList.prototype.push = function (snow) {
    	this.list.push (snow);
    }
    SnowList.prototype.update = function () {
    	for (var i = 0, len = this.list.length; i < len; i++) {
    		this.list[i].update();
    	}
    }
    SnowList.prototype.draw = function (cxt) {
    	for (var i = 0, len = this.list.length; i < len; i++) {
    		this.list[i].draw (cxt);
    	} 
    }
    SnowList.prototype.get = function (i) {
    	return this.list[i];
    }
    SnowList.prototype.size = function () {
    	return this.list.length;
    }

    /**
     * Generate random x-pos, y-pos or fn functions
     * @param  {string} option x|y|fnx|fny
     * @return {int|Function} 
     */
    function getRandom (option) {
    	var ret, random;
    	switch (option) {
    		case 'x': 
    			ret = Math.random () * window.innerWidth;
    			break;
    		case 'y':
    			ret = Math.random () * window.innerHeight;
    			break;
    		case 'r':
    			ret = 2 + (Math.random () * 6);
    			break;
    		case 'fnx':
    			random = 27 + Math.random () * 100;
    			ret = function (x, y) {
    				return x +  0.5 * Math.sin (y / random);
    			};
    			break;
    		case 'fny':
    			random = 0.4 + Math.random () * 1.4
    			ret = function (x, y) {
    				return y + random;
    			};
    			break;
    	}
    	return ret;
    }

    // Start snow
    function startSnow () {
    	// Create canvas
	    var canvas = document.createElement ('canvas'), cxt;
	    canvas.height = window.innerHeight;
	    canvas.width = window.innerWidth;
	    canvas.setAttribute ('style', 'position: fixed;left: 0;top: 0;pointer-events: none;');
	    canvas.setAttribute ('id', 'canvas_snow');
	    document.getElementsByTagName ('body')[0].appendChild (canvas);
	    cxt = canvas.getContext ('2d');
	    // Create snow objects
	    var snowList = new SnowList();
	    for(var i = 0; i < 200; i++){
	    	var snow, randomX, randomY, randomR, randomFnx, randomFny;
	    	randomX = getRandom ('x');
	    	randomY = getRandom ('y');
	    	randomR = getRandom ('r');
	    	randomFnx = getRandom('fnx');
	    	randomFny = getRandom('fny');
	    	snow = new Snow (randomX, randomY, randomR, {
		    	x: randomFnx,
		    	y: randomFny
		    });
		    snow.draw (cxt);
		    snowList.push (snow);
	    }
	    // Update snow position data, and redraw them in each frame
	    requestAnimationFrame (function(){
	    	cxt.clearRect (0, 0, canvas.width, canvas.height);
	    	snowList.update ();
	    	snowList.draw (cxt);
	    	requestAnimationFrame (arguments.callee);
	    })
    }
    
    // Handle window resize
    window.onresize = function () {
    	var canvasSnow = document.getElementById('canvas_snow');
    	canvasSnow.width = window.innerWidth;
    	canvasSnow.height = window.innerHeight;
    }

    // Let it snow O(∩_∩)0
    startSnow ();
</script>
</body> 
</html>

技术分享

canvas下雪效果