Let it snow… let it snow (the return)

Last year I published a post on html5 canvas snow generated with some JS.

To be honest it was a little sh*te… so this year I created some better snow and thought I’d share it with you all to use.

This is an example of what you’re aiming to create:

As you can (hopefully) see it produces snow flakes of varying size and weight that float at random speeds and directions (all whilst spinning in at a random speed and direction).

As if that weren’t enough – thanks to @kgu the JS now measures the CPU impact and alters the amount of snow that is generated so that it is produced at a rate the viewer’s computer can handle.

In this version the background of the canvas element is red but this can be altered in the CSS. I’ve ¬†used this with a transparent background and a absolute position to overlay it above some graphics in the background before.

Play about… have fun… and let me know if it’s worked for you in the comments below.

The HTML:

<canvas id="snowSpace" width="500" height="300"></canvas>

The JS:

var a_canvas = document.getElementById("snowSpace"),
		c = a_canvas.getContext('2d'),
		particles = [],
		j = 0,
		canvasWidth = document.getElementById("snowSpace").width,
		canvasHeight = document.getElementById("snowSpace").height,
		snowColour = "white";
	//LET'S INPUT SOME CODE HERE:
	setInterval(draw, 1000/60);
	var t,t1
	t=new Date();
	t1=new Date();
	function draw(){
		c.clearRect(0,0,canvasWidth,canvasHeight);
		var p = new Particle();
	    if (j%10==0 &&t1.getTime()- t.getTime()<1){
				particles.push(p);
	    }
	t=new Date();
		//RUN THROUGH AN ARRAY OF SNOW FLAKES:
		for(var i = 0; i<particles.length; i++) {
 			p = particles[i];
 			c.save();
 			c.translate(p.xPos,p.yPos);
 			c.rotate(p.ang);
 			c.scale(p.size,p.size);
 			drawFlake(p.thickness);
 			c.restore();
 			p.xPos += p.xVel;
 			p.yPos += p.yVel;
 			p.ang += p.spin;
 			if(p.yPos>canvasHeight*2){
				particles.shift();
			}
		}
		particles.xVel += random(-0.4, 0.4);
		j+=1;
		t1=new Date();
	}
	function Particle(){
		this.size = random(0.05,0.15);
		this.xPos = random(-30, canvasWidth + 30);
		this.yPos = -80;
		this.xVel = random(-0.7, 0.7);
		this.yVel = random(1, 2);
		this.ang = random (-0.5,0.5);
		this.spin = random (-0.05,0.05);
	    this.thickness = random(2,20);
	}
	function drawCross(thickness){
	    c.beginPath();
		c.moveTo(-40, -40);
	    c.lineTo(40,40);
	    c.moveTo(-40, 40)
	    c.lineTo(40, -40)
	    c.lineWidth=thickness ;
		c.strokeStyle = snowColour;
		c.stroke();
	}
	function drawFlake(thickness) {
		c.save();
			drawCross(thickness);
		c.rotate(Math.PI / 4);
			drawCross(thickness);
		c.restore();
	}
	//CREATE RANDOM FUNCTION
	function random(min, max) {
		return Math.random() * (max - min) + min;
	}

The CSS

#snowSpace {
	background: #b80333;
	margin:0;
	overflow:hidden;
}