API Docs for: 0.3.0
Show:

File: modules/Graphic/Camera.js

/**
 * @module Graphic
 * @namespace Graphic
 */

var TW = TW || {};
define(['../Math/Matrix2D'], function(Matrix2D) {

	TW.Graphic = TW.Graphic || {};


	/**
	 * The Camera class allow you to create a camera who has the purpose to simulate a camera on some layers.
	 * Each {{#crossLink "Graphic.Layer" }}Layer{{/crossLink}} or {{#crossLink "Graphic.Window" }}Window{{/crossLink}}
	 * contain a camera for moving te point of view displayed.
	 *
	 * ### Manipulate the camera
	 *
	 * The movement of the camera is based on an internal matrix, representing the point of view
	 * of the camera.
	 * This class provide an useful way to moving in the space without using directly matrices.
	 * All manipulation methods matrix provided are applied in a fixed order:
	 *
	 *  - translation
	 *  - rotation
	 *  - skew
	 *  - scale
	 *
	 * the aim is to use each type of transformation separately, regardless of the order of method calls.
	 *
	 *
	 * It's also possible to directly use the matrix methods, but both methods are not compatible,
	 * because calling a method from the camera will overwrite the matrix.<br />
	 * __If you choose to directly manipulate the matrix, be careful to not use matrix transformations method
	 * provided by the Camera class.__
	 *
	 * ### Extending the class
	 *
	 * The Camera class provide only basic features and is destined to be extended.
	 * The two important methods are `prepare` and `update`
	 *
	 *  - `prepare` is called for preparing the graphic rendering (just applying matrix by default).<br />
	 *      {{#crossLink "Graphic.Camera/prepare" }}More information here{{/crossLink}}
	 *  - `update` is an optional method (and is not provided in this class) called regularly,
	 *  useful for adding a dynamic behavior.<br />
	 * Note that you can take advantage of Javascript by adding directly an `update` method on the Camera instance.
	 *
	 * @class Camera
	 * @constructor
	 */
	function Camera() {
		/**
		 * matrix used for define the view.
		 *
		 * Note that modify it don't automatically refresh the associated layer.
		 * You should refresh the Layer after this operation.
		 *
		 * Directly modifing the matrix is not compatible with other matrix Camera's method (`translate`, `rotate`,
		 * `skew` or `scale`).
		 * Calling one of these method will recreate the matrix and erasing your matrix.
		 * For applying transformations, you should modify directly the matrix.
		 *
		 * @property {Matrix2D} matrix
		 */
		this.matrix = new Matrix2D();

		this._translation = {x: 0, y: 0 };
		this._rotation = 0;
		this._scale = {x: 1, y: 1 };
		this._skew = {a: 0, b: 0 };
	}

	/**
	 * prepare is called before each draw on the canvas.
	 * The canvas 2D context must be completely reset.
	 *
	 * By default, context matrix are multiplied by internal matrix.
	 * save and restore operations are done by the caller.
	 *
	 * @method prepare
	 * @param {CanvasRenderingContext2D} context The canvas context which will be used to draw.
	 */
	Camera.prototype.prepare = function(context) {
		context.clearRect(0, 0, context.canvas.width, context.canvas.height);
		this.matrix.transformContext(context);
	};

	/**
	 * Apply a translation to the camera.
	 *
	 * @method translate
	 * @chainable
	 * @param x
	 * @param y
	 * @return {Camera}
	 */
	Camera.prototype.translate = function(x, y) {
		this._translation = {x: x, y: y};
		this._updateMatrix();
		return this;
	};

	/**
	 * Apply a rotation to the camera.
	 *
	 * @method rotate
	 * @chainable
	 * @param {Number} angle rotation angle in degrees.
	 * @return {Camera}
	 */
	Camera.prototype.rotate = function(angle) {
		this._rotation = angle;
		this._updateMatrix();
		return this;
	};
	/**
	 * Apply a scale transformation to the camera.
	 *
	 * @method scale
	 * @chainable
	 * @param {Number} x
	 * @param {Number} y
	 * @return {Camera}
	 */
	Camera.prototype.scale = function(x, y) {
		this._scale = {x: x, y: y };
		this._updateMatrix();
		return this;
	};

	/**
	 * Apply a skew transformation to the camera.
	 *
	 * @method skew
	 * @chainable
	 * @param {Number} a
	 * @param {Number} b
	 * @return {Camera}
	 */
	Camera.prototype.skew = function(a, b) {
		this._skew = {a: a, b: b};
		this._updateMatrix();
		return this;
	};

	/**
	 * Update the matrix after a transformation.
	 * @method _updateMatrix
	 * @protected
	 */
	Camera.prototype._updateMatrix = function() {
		this.matrix.identity()
			.translate(- this._translation.x, - this._translation.y)
			.rotate(this._rotation)
			.skew(this._skew.a, this._skew.b)
			.scale(this._scale.x, this._scale.y);
	};

	TW.Graphic.Camera = Camera;
	return Camera;
});