Archive

Archive for November, 2011

Fun with HTML5 canvas

November 14th, 2011 Comments off

Demonstrating Canvas API…

var Point = function(x, y) {
	this.x = x;
	this.y = y;
}

var Circle = function(pos, dir, color, radius) {
	this.pos = pos;
	this.dir = dir;
	this.color = color;
	this.radius = radius;
};

Circle.prototype.move = function(speed, w, h) {
	this.pos.x += this.dir.x * speed;
	if (this.pos.x < 0) {
		this.pos.x = 0;
		this.dir.x = -this.dir.x;
	} else if ((this.pos.x + this.radius*2) > w) {
		this.pos.x = w - this.radius*2;
		this.dir.x = -this.dir.x;
	}

	this.pos.y += this.dir.y * speed;
	if (this.pos.y < 0) {
		this.pos.y = 0;
		this.dir.y = -this.dir.y;
	} else if ((this.pos.y + this.radius*2) > h) {
		this.pos.y = h - this.radius*2;
		this.dir.y = -this.dir.y;
	}
};

Circle.prototype.draw = function(context) {
	context.beginPath();
	context.arc(this.pos.x + this.radius, this.pos.y + this.radius, this.radius, 0, Utils.degreesToRadians(360), true);
	context.fillStyle = this.color;
	context.fill();
};

var Frame = function(canvasId, numberOfCircles) {
	this.canvas = document.getElementById(canvasId);
	this.speed = 1;
	this.numberOfCircles ||= 5;
	this.circles = [];
};

Frame.prototype.start = function() {
	for (var i = 0; i < this.numberOfCircles; i++) {
		this.addBall();
	}
	var self = this;
	setInterval(function() { self.update(); }, 25);
};

Frame.prototype.speedUp = function() {
	this.speed++;
};

Frame.prototype.addBall = function() {
	var circle = new Circle(Utils.randPos(this.canvas.width, this.canvas.height), Utils.randDir(), Utils.randColor(), Utils.randRadius());
	this.circles.push(circle);
};

Frame.prototype.update = function() {
	var canvas = this.canvas;
	var context = canvas.getContext("2d");

	context.clearRect(0, 0, canvas.width, canvas.height);
	context.strokeStyle = '#000000';
	context.strokeRect(0, 0, canvas.width, canvas.height);

	for (var i = 0; this.circles[i]; i++) {
		var circle = this.circles[i];
		circle.move(this.speed, canvas.width, canvas.height);
		circle.draw(context);
	}
};

var Utils = {
	degreesToRadians: function(degrees) {
		return (degrees * Math.PI) / 180;
	},

	randDir: function() {
		return new Point((Math.random() > 0.5 ? 1 : -1) * Math.random(),
						 (Math.random() > 0.5 ? 1 : -1) * Math.random());
	},

	randPos: function(w, h) {
		return new Point(Utils.rand(w), Utils.rand(h));
	},

	randColor: function() {
		var letters = '0123456789ABCDEF'.split('');
	    var color = '#';
	    for (var i = 0; i < 6; i++ ) {
	        color += letters[Utils.rand(15)];
	    }
	    return color;
	},

	randRadius: function() {
		return Utils.rand(5) + 5;
	},

	rand: function(max) {
		return Math.round(Math.random() * max);
	}
};

Array.prototype.each = function(f) {
	for (var i = 0; this[i]; i++) f(this[i]);
};

window.onload = function() {
	var frames = [new Frame("canvas1"), new Frame("canvas2")];
	frames.each(function(f) { f.start(); });

	document.getElementById("btnAddSpeed").onclick = function() {
		frames.each(function(f) { f.speedUp(); });
	};

	document.getElementById("btnAddBall").onclick = function() {
		frames.each(function(f) { f.addBall(); });
	};
};

Place that script in a page with these elements

<canvas id="canvas1"></canvas>
<canvas id="canvas2"></canvas>
<br/>
<input type="button" id="btnAddSpeed" value="Add Speed">
<input type="button" id="btnAddBall" value="Add Balls">
Categories: Uncategorized Tags: , ,