Spider-Man Crawls on the Canvas

Wanted to use a sprite without a library of any kind. Practiced tile animation, translating the context and flipping the image.

by Brian Cribb

HTML

<div id="canvasContainer"></div>
<p>Spider-Man will keep crawling, but you can pause him with the spacebar. Arrow keys will turn him, but he flips along his center-bottom so using the up arrow puts him above the canvas.</p>

CSS

canvas {
    background:#dddddd;
}
p {
    max-width:500px;
}
canvas, p {
    display:block;
    margin: 0 auto 10px;
}

JavaScript

/*
INSPIRATIONS:
Structure inspired by:
	http://viget.com/extend/2666
Page Visibility API and Polyfill for vendor prefixes:
	http://stackoverflow.com/questions/1060008/is-there-a-way-to-detect-if-a-browser-window-is-not-currently-active
	http://www.w3.org/TR/page-visibility/
	http://caniuse.com/#feat=pagevisibility
	http://jsfiddle.net/0GiS0/cAG5N/
*/
window.requestAnimFrame = (function(){
	return  window.requestAnimationFrame       || 
			window.webkitRequestAnimationFrame || 
			window.mozRequestAnimationFrame    || 
			window.oRequestAnimationFrame      || 
			window.msRequestAnimationFrame     || 
			function( callback ){
			window.setTimeout(callback, 1000 / 60);
			};
})();

var APP = {
	props: {
		keycodes: {
			SPACE: 32,
			LEFT: 37,
			RIGHT: 39,
			UP: 38,
			DOWN: 40
		},
		paused: false,
		textColor: '#333333',
		fpsLast:0,
		avgFPS:0
	},
	pause: function() {
		console.log('APP.pause()');
		APP.props.paused = true; // Next animationFrame won't be called if this is true.
	},
	play: function() {
		console.log('APP.play()');
		APP.core.then = Date.now();
		APP.props.paused = false;
		APP.core.frame();
	},
	init: function() {

		// Setting strings to match vendor visibility names.
		if (typeof document.hidden !== "undefined") {
			APP.hidden = "hidden", APP.visibilityChange = "visibilitychange", APP.visibilityState = "visibilityState";
		} else if (typeof document.mozHidden !== "undefined") {
			APP.hidden = "mozHidden", APP.visibilityChange = "mozvisibilitychange", APP.visibilityState = "mozVisibilityState";
		} else if (typeof document.msHidden !== "undefined") {
			APP.hidden = "msHidden", APP.visibilityChange = "msvisibilitychange", APP.visibilityState = "msVisibilityState";
		} else if (typeof document.webkitHidden !== "undefined") {
			APP.hidden = "webkitHidden", APP.visibilityChange = "webkitvisibilitychange", APP.visibilityState = "webkitVisibilityState";
		}
		// We'll check this against the document in the listener...