Demo: http://liuyanzhi08.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>
出处: http://blog.csdn.net/nancle/article/details/42238943