API Docs for: 0.3.0
Show:

File: modules/Graphic/Layer.js

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

var TW = TW || {};
define(['./GraphicObject', './SpatialContainer', './Camera', '../Utils/inherit', '../Utils/Polyfills'],
       function(GraphicObject, SpatialContainer, Camera, inherit) {

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


	       /**
	        * The Layer class can hold several GraphicObjects and it provides some transformations methods to move or
	        * scale all the GraphicalObjects that it contains. This is helpful when you want for example apply
	        * the same plane transformation to some GraphicalObjects.
	        *
	        * @class Layer
	        * @extends Graphic.GraphicObject
	        * @constructor
	        * @param {Object} params All properties given to
	        *   {{#crossLink "Graphic.GraphicObject"}}GraphicObject{{/crossLink}} are available.
	        *   @param {Camera} [params.camera] camera used be the layer. if not set, a new `Camera` is created.
	        *   @param {SpatialContainer} [params.spatialContainer]
	        *   @param {CanvasRenderingContext2D} [params.localContext] you can set directly
	        *   the graphic canvascontext used by the layer.
	        */
	       function Layer(params) {
		       GraphicObject.call(this, params);
		       params = params || {};

		       /**
		        * camera of the layer.
		        *
		        * **Note: this property should be modified only with `setAttr`.**
		        *
		        * @property {Camera} camera
		        */
		       this.camera = params.camera || new Camera();

		       /**
		        * **Note: this property should be modified only with `setAttr`.**
		        * @property {SpatialContainer} spatialContainer
		        */
		       this.spatialContainer = params.spatialContainer || new SpatialContainer();

		       /**
		        * All layers use a local 2D context canvas for rendering object.
		        * It is used as a cache layer, and redrawn only when needed.
		        *
		        * Directly set the cache context can be usefull for debug.
		        *
		        * **Note: this property should be modified only with `setAttr`.**
		        *
		        * @property {CanvasRenderingContext2D} localContext
		        */
		       this.localContext = params.localContext || document.createElement('canvas').getContext("2d");

		       this.localContext.canvas.width = this.width;
		       this.localContext.canvas.height = this.height;

		       /**
		        * indicate when the cache must be updated.
		        *
		        * @property {Boolean} _needToRedraw
		        * @private
		        */
		       this._needToRedraw = true;
	       }

	       inherit(Layer, GraphicObject);


	       /**
	        * Setter availlable for updating attibuts and correctly clear the caches.
	        * You can set all attributes supported by this instance
	        * (see the GraphicObject constructor for common available properties)
	        *
	        * @example
	        *
	        *      object.setAttr({
			*          width: 20,
	        *          height: 20
	        *      });
	        *
	        *      object.setAttr({
	        *          pos: {
	        *              x: 0,
	        *              y: 0
	        *          }
	        *      });
	        *
	        * @method setAttr
	        * @param {Object} attrs Layer attributs. See the constructor for more details.
	        * @chainable
	        */
	       Layer.prototype.setAttr = function(attrs) {
		       GraphicObject.setAttr(attrs);
		       this.localContext.canvas.width = this.width;
		       this.localContext.canvas.height = this.height;
	       };

	       /**
	        * This method allow the user to draw on the canvas's context.
	        * If nothing has changed in the childs of the layer, then a buffered layer is printed on the canvas.
	        * Otherwise all the canvas is redraw.
	        *
	        * @method draw
	        * @param {CanvasRenderingContext2D} context
	        */
	       Layer.prototype.draw = function(context) {
		       if (this._needToRedraw === true) {
			       this.localContext.save();
			       this.camera.prepare(this.localContext);
			       this.spatialContainer.applyToZone([
				                                         {x: 0, y: 0},
				                                         {x: 0, y: this.height},
				                                         {x: this.width, y: this.height},
				                                         {x: this.width, y: 0}
			                                         ], function(child) {
				       child.draw(this.localContext);
			       }.bind(this));
			       this.localContext.restore();
			       this._needToRedraw = false;
		       }
		       context.save();
		       context.translate(this.x, this.y);
		       this.matrix.transformContext(context);
		       context.drawImage(this.localContext.canvas, -this.centerPoint.x, -this.centerPoint.y, this.width,
		                         this.height);
		       context.restore();
	       };

	       /**
	        * This method will allow you to add a child to the current Layer.
	        *
	        * @method addChild
	        * @param {GraphicObject} graphicObject this parameter must be a valid GraphicObject, otherwise the method
	        * will have an undefined behavior.
	        */
	       Layer.prototype.addChild = function(graphicObject) {
		       if (!(graphicObject instanceof GraphicObject)) {
			       throw new Error("bad param");
		       }
		       this.spatialContainer.addElement(graphicObject);
		       graphicObject.parent = this;
		       this.onChange(graphicObject);
	       };

	       /**
	        * This method will allow you to remove a child from the current Layer.
	        *
	        * @method rmChild
	        * @param {GraphicObject} graphicObject this parameter is the GraphicObject that the method will try
	        * to find inside the child of the current layer.
	        */
	       Layer.prototype.rmChild = function(graphicObject) {
		       this.spatialContainer.removeElement(graphicObject);
		       this.onChange(null);
	       };

	       /**
	        * This method will allow you to update the layer and all the childs within the layer.
	        *
	        * @method update
	        */
	       Layer.prototype.update = function(elapsedTime) {
		       this.spatialContainer.applyAll(function(child) {
			       if (child.update) {
				       child.update(elapsedTime);
			       }
		       });
	       };

	       /**
	        * This method will be called when a child is changed.
	        * By using this method it will notice the current Layer to redraw the local canvas.
	        *
	        * This method is called automatically when a child object change.
	        * You can call this method for clear internal cache.
	        *
	        * @method onChange
	        * @param {GraphicObject} [child] this object represent the child who has been changed.
	        */
	       Layer.prototype.onChange = function(child) {
		       this._needToRedraw = true;
		       return this.notifyParentChange();
	       };

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