Canvas Parallax Scroll

by jsfiddle/jaredwilli

by Anov Siradj

HTML

<input id='animateButton' type='button' value='Animate'/>
<ul>
    <li><a href="#panel1">1</a></li>
    <li><a href="#panel2">2</a></li>
    <li><a href="#panel3">3</a></li>
    <li><a href="#panel4">4</a></li>
    <li><a href="#panel5" class="active">5</a></li>
    <li><a href="#panel6">6</a></li>
    <li><a href="#panel7">7</a></li>
    <li><a href="#panel8">8</a></li>
    <li><a href="#panel9">9</a></li>
    <li><a href="#panel10">10</a></li>
    <li><a href="#panel11">11</a></li>
    <li><a href="#panel12">12</a></li>
    <li><a href="#panel13">13</a></li>
    <li><a href="#panel14">14</a></li>
    <li><a href="#panel15">15</a></li>
</ul>

<canvas id="bgCanvas" width="1000" height="440">You need to a newer browser to see this awesomeness!</canvas>

<div id="imgs" class="visuallyhidden">
    <img id="layer5" src="http://anti-code.com/imgs/tree-twotrunks.png" />
	<img id="layer4" src="http://anti-code.com/imgs/tree.png" />
	<img id="layer1" src="http://anti-code.com/imgs/smalltree.png" />
	<img id="smCloud" src="http://anti-code.com/imgs/sky.png" />
	<img id="medCloud" src="http://anti-code.com/imgs/grass.png" />
	<img id="bigCloud" src="http://anti-code.com/imgs/grass2.png" />
</div>

CSS

#animateButton,
ul {
    position: absolute;
    top: 10px;
    left: 10px;
    z-index: 2;
}
ul {
    list-style: none;
    z-index: 1;
}
ul li {
    display: inline-block;
    width: auto;
    margin: 0 10px;
}


canvas {
	position: fixed;
}
.visuallyhidden {
    border: 0; 
    clip: rect(0 0 0 0); 
    height: 1px; 
    margin: -1px; 
    overflow: hidden; 
    padding: 0; 
    position: absolute; 
    width: 1px;
}

body {
    background: #dddddd;
}

#canvas {
    position: absolute;
    left: 20px;
    top: 30px;
    background: #ffffff;
    cursor: crosshair;
    margin-left: 10px;
    margin-top: 10px;
    -webkit-box-shadow: 4px 4px 8px rgba(0,0,0,0.5);
    -moz-box-shadow: 4px 4px 8px rgba(0,0,0,0.5);
    box-shadow: 4px 4px 8px rgba(0,0,0,0.5);
}

JavaScript

if (!window.requestNextAnimationFrame) {
	window.requestNextAnimationFrame = (function() {
		return window.webkitRequestAnimationFrame ||
			   window.mozRequestAnimationFrame 	  ||
			   window.oRequestAnimationFrame 	  ||
			   window.msRequestAnimationFrame 	  ||
		function(callback, element) {
			window.setTimeout(callback, 1000 / 60);
		};
	})();
}


(function(win, d) {

	var canvas = d.getElementById('bgCanvas'),
		ctx = canvas.getContext('2d'),
		animateButton = d.getElementById('animateButton'),

		tree = new Image(),
		nearTree = new Image(),
		smCloud = new Image(),
		medCloud = new Image(),
		bigCloud = new Image(),
		grass = new Image(),
		grass2 = new Image(),
		sky = new Image(),

		paused = true,
		lastTime = 0,
		fps = 60,
		lastFpsUpdate = {
			time: 0,
			value: 0
		},

		skyOffset = 0,
		grassOffset = 0,
		treeOffset = 0,
		nearTreeOffset = 0,

		TREE_VELOCITY = 20,
		FAST_TREE_VELOCITY = 40,
		SKY_VELOCITY = 8,
		GRASS_VELOCITY = 75;


	// Functions.....................................................

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

	function draw() {

		ctx.save();
			skyOffset = skyOffset < canvas.width ? skyOffset + SKY_VELOCITY / fps : 0;
			grassOffset = grassOffset < canvas.width ? grassOffset + GRASS_VELOCITY / fps : 0;
			treeOffset = treeOffset < canvas.width ? treeOffset + TREE_VELOCITY / fps : 0;
			nearTreeOffset = nearTreeOffset < canvas.width ? nearTreeOffset + FAST_TREE_VELOCITY / fps : 0;

			// sky
			ctx.save();
				ctx.translate(-skyOffset, 0);
					ctx.drawImage(sky, 0, 0);
					ctx.drawImage(sky, sky.width - 2, 0);
			ctx.restore();

			// small tree
			ctx.save();
				ctx.translate(-treeOffset, 0);
					ctx.drawImage(tree, 100, 240);
					ctx.drawImage(tree, 1100, 240);
					ctx.drawImage(tree, 400, 240);
					ctx.drawImage(tree, 1400, 240);
					ctx.drawImage(tree, 700, 240);
					ctx.drawImage(tree, 1700, 240);
			ctx.restore();

			//...