Snowfall

by Mark

HTML

<canvas id="canvas"></canvas>

CSS

/*body{margin:0;height:100%;}
canvas{
    position:absolute;top:0;left:0
    background-image: linear-gradient(top, rgb(105,173,212) 0%, rgb(23,82,145) 84%);
    background-image: -o-linear-gradient(top, rgb(105,173,212) 0%, rgb(23,82,145) 84%);
    background-image: -moz-linear-gradient(top, rgb(105,173,212) 0%, rgb(23,82,145) 84%);
    background-image: -webkit-linear-gradient(top, rgb(105,173,212) 0%, rgb(23,82,145) 84%);
    background-image: -ms-linear-gradient(top, rgb(105,173,212) 0%, rgb(23,82,145) 84%);
    
    background-image: -webkit-gradient(
        linear,
        left bottom,
        left top,
        color-stop(0, rgb(105,173,212)),
        color-stop(0.84, rgb(23,82,145))
    );
} */

@charset "UTF-8";article,body,div,footer,form,header,hgroup,html,img,nav,p,section,span,table{margin:0;padding:0;border:0}article,footer,header,hgroup,nav,section{display:block}body{color:#fff;font-family:'Helvetica Neue',Arial,sans-serif;font-size:14px;line-height:1.3;background:#123d60 url(img/bg-sky.png?v=793d3954ad8c) repeat-x top left;background-size:11px 420px}body.subpage{background-size:11px 250px}a{color:#8fd8f6;text-decoration:none}a:visited{color:#c7e8f6}h1,h2,h3,h4,h5,h6{font-weight:400;margin:0 0 .5em}h1{font-size:180%}h2{font-size:150%}h3{font-size:130%}h4{font-size:110%}p{margin-bottom:1em}#snow{margin:0 auto;width:960px;height:0}#snowcanvas{margin-left:-300px;width:1560px;height:420px}section.wrapper{width:960px;margin:0 auto;position:relative}header.top{background:url(img/bg-glow-top.png?v=7f2adbfbbbf7) no-repeat center top,url(img/bg-hills.png?v=8edd6027e7dd) no-repeat center bottom;background-size:1021px;height:420px;overflow:hidden}header.subpage{height:250px;background:url(img/snow-flakes.png?v=8c2e42253ec6) no-repeat center 20px,url(img/bg-glow-top.png?v=7f2adbfbbbf7) no-repeat center top,url(img/bg-hills.png?v=8edd6027e7dd) no-repeat center bottom;background-size:1021px}header.top .logo-link{display:block;margin:100px auto...

JavaScript

(function() {
    // Animation Frame
    var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame ||
    function(callback) {
        window.setTimeout(callback, 1000 / 60);
    };
    window.requestAnimationFrame = requestAnimationFrame;
})();

// Flake Objects
var flakes = [],
    canvas = document.getElementById("canvas"),
    ctx = canvas.getContext("2d"),
    flakeCount = 400,
    mX = -100,
    mY = -100

    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;

function snow() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    for (var i = 0; i < flakeCount; i++) {
        var flake = flakes[i],
            x = mX,
            y = mY,
            minDist = 150,
            x2 = flake.x,
            y2 = flake.y;

        var dist = Math.sqrt((x2 - x) * (x2 - x) + (y2 - y) * (y2 - y)),
            dx = x2 - x,
            dy = y2 - y;

        if (dist < minDist) {
            var force = minDist / (dist * dist),
                xcomp = (x - x2) / dist,
                ycomp = (y - y2) / dist,
                deltaV = force / 2;

            flake.velX -= deltaV * xcomp;
            flake.velY -= deltaV * ycomp;

        } else {
            flake.velX *= .98;
            if (flake.velY <= flake.speed) {
                flake.velY = flake.speed
            }
            flake.velX += Math.cos(flake.step += .05) * flake.stepSize;
        }

        ctx.fillStyle = "rgba(255,255,255," + flake.opacity + ")";
        flake.y += flake.velY;
        flake.x += flake.velX;
            
        if (flake.y >= canvas.height || flake.y <= 0) {
            reset(flake);
        }


        if (flake.x >= canvas.width || flake.x <= 0) {
            reset(flake);
        }

        ctx.beginPath();
        ctx.arc(flake.x, flake.y, flake.size, 0, Math.PI * 2);
        ctx.fill();
    }
    requestAnimationFrame(snow);
};

function...