API Docs for: 0.3.0
Show:

File: modules/Graphic/SpatialContainer.js

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

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

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

	/**
	 * A spatial container is a data structure used for storage of spatial 2D objects
	 * (generally {{#crossLink "Graphic.GraphicObject" }}GraphicObject{{/crossLink}}).
	 * It propose many method for manipulate these objects using theirs coordinates.
	 *
	 * This class provide a basic implementation of all methods,
	 * and also represent an interface to others spatial containers.
	 * Different containers provides different complexities, and for each situation,
	 * someone are more adapted than others.
	 *
	 * @class SpatialContainer
	 * @constructor
	 */
	function SpatialContainer() {
		this._containerList = [];
	}

	/**
	 * This method allow you to add a GraphicalObject to the SpatialContainer
	 *
	 * @method addElement
	 * @param {Object} element this object will be added to the internal list of the SpatialContainer.
	 *  element *SHOULD BE* a GraphicObject, otherwise the spatial container would have undetermined behavior.
	 */
	SpatialContainer.prototype.addElement = function(element) {
		this._containerList.push(element);
		this._containerList.sort(function(a, b) {
			return (a.zIndex - b.zIndex);
		});
	};

	/**
	 * This method allow you to remove a graphical element from the SpatialContainer
	 *
	 * @method removeElement
	 * @param {Object} element the reference to the object to remove from the SpatialContainer List.
	 * @return {Boolean} `true` if the element to remove from the list was found. Otherwise it returns `false`.
	 */
	SpatialContainer.prototype.removeElement = function(element) {
		for (var i = 0; i < this._containerList.length; i++) {
			if (element === this._containerList[i]) {
				this._containerList.splice(i, 1);
				return true;
			}
		}
		return false;
	};

	/**
	 * This method allow you to apply a callback for every GraphicObject contained in the SpatialContainer.
	 *
	 * The callback shouldn't remove directly an element until the end of `applyAll`.
	 * The behavior in this case is undefined.
	 *
	 * @method applyAll
	 * @param {Function} callback must be a callback function
	 *  @param {Object} callback.element element contained in spatial container.
	 *
	 * @example
	 *
	 *     container.applyAll(function(element) {
	 *          element.draw();
	 *     });
	 */
	SpatialContainer.prototype.applyAll = function(callback) {
		for (var i = 0; i < this._containerList.length; i++) {
			callback(this._containerList[i]);
		}
	};

	/**
	 * This method allow you to apply a callback to the GraphicObject who are at the specified position.
	 *
	 * @method applyToPoint
	 * @param {Number} x the x position where the GraphicObject must be to get the callback applied on them
	 * @param {Number} y the y position where the GraphicObject must be to get the callback applied on them.
	 * @param {Function} callback to apply to every GraphicObject which position match the x, y parameters.
	 */
	SpatialContainer.prototype.applyToPoint = function(x, y, callback) {
		var length = this._containerList.length;

		for (var i = 0; i < length; i++) {
			var target = this._containerList[i];

			var point = target.matrix.inverse().multiplyVector(new Vector2D(x - target.x, y - target.y));
			point.add(target.centerPoint);

			if (point.x >= 0 && point.x <= target.width &&
			    point.y >= 0 && point.y <= target.height) {
				callback(this._containerList[i]);
			}
		}
	};

	/**
	 * This method allow you to apply a callback only on the object that are inside of the polygon
	 * specified by the points.
	 *
	 * The goal is to process optimization to apply callback only if necessary, for improve speed. Objects that are not
	 * in the zone can be used: somes optimizations can be aproximate.
	 *
	 *
	 * The default method use directly `applyAll` and no optimization is done. (selecting good and bas objects
	 * whithout tree structure take more time than display them)
	 *
	 * @method applyToZone
	 *
	 * @param {Array} pointsArray array of points like `{{10,0},{0,10},{2,3}}
	 *  *Note that the polygon MUST BE composed at least of 3 points,
	 *  otherwise the method will throw an error.*
	 *
	 * @param {Function} callback function to be called on every GraphicObject that are inside of
	 *  the polygon specified by pointsArray.
	 */
	SpatialContainer.prototype.applyToZone = function(pointsArray, callback) {
		if (!(pointsArray && pointsArray.length >= 3)) {
			throw new Error("Bad params");
		}

		this.applyAll(callback);
	};

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