/** * @module EaselJS Learning * @namespace springroll * @requires Core, Learning */ (function() { // Include classes var ApplicationPlugin = include('springroll.ApplicationPlugin'), Point = include('createjs.Point'), Debug; /** * @class Application */ var plugin = new ApplicationPlugin(); /** * The last interactive position * @property {createjs.Point} _currentPosition * @private */ var _currentPosition = new Point(); /** * Helper point for normalizing position * @property {createjs.Point} _helperPoint * @private */ var _helperPoint = new Point(); // Init the animator plugin.setup = function() { if (!Debug) { Debug = include('springroll.Debug', false); } /** * Some games need to send additional parameters to the tracker's * offClick event. They may set them here as needed. These parameters are appended * to the normal offClick data. * @property {Array} offClickParams */ this.offClickParams = []; /** * Keep track of the last Pointer ID * @property {int} _lastPointerID * @private */ this._lastPointerID = null; /** * For learning events, we want to send consistent data when sending * positions. This helper method generates that data. * In the future, we may return an object with known properties, * but for now we are returning an object of {x:int, y:int, * stage_width:int, stage_height:int} in unscaled numbers. * * @method normalizePosition * @param {createjs.DisplayObject|createjs.Point} pos A display object or point to use. * @param {createjs.DisplayObject} [coordSpace] The coordinate space the position is in, so * it can be converted to global space. If * omitted and <code>pos</code> is a * DisplayObject, <code>pos.parent</code> will * be used. * @return {Object} {x:int, y:int, stage_width:int, stage_height:int} */ /** * For learning events, we want to send consistent data when sending * positions. This helper method generates that data. * In the future, we may return an object with known properties, * but for now we are returning an object of {x:int, y:int, * stage_width:int, stage_height:int} in unscaled numbers. * * @method normalizePosition * @param {Number} x The x position * @param {Number} y The y position * @param {createjs.DisplayObject} [coordSpace] The coordinate space the position is in, so * it can be converted to global space. * @return {Object} {x:int, y:int, stage_width:int, stage_height:int} */ this.normalizePosition = function(x, y, coordSpace) { //detect Points and DisplayObjects if (x.hasOwnProperty("x")) { coordSpace = y || x.parent; y = x.y; x = x.x; } if (coordSpace && coordSpace.localToGlobal) { var globalPoint = coordSpace.localToGlobal(x, y, _helperPoint); x = globalPoint.x; y = globalPoint.y; } var display = this.display; return { x: x | 0, y: y | 0, stage_width: display.width, stage_height: display.height }; }; /** * For learning events, we want to send consistent data when sending * Position. This helper method generates that data for the * current stage position of mouse or touch. We are returning an object of * `{x:int, y:int, stage_width:int, stage_height:int}` in unscaled numbers. * * @method currentPosition * @return {Object} `{x:int, y:int, stage_width:int, stage_height:int}` */ this.currentPosition = function() { return this.normalizePosition(_currentPosition); }; }; // Check for dependencies plugin.preload = function(done) { if (!this.learning) { if (DEBUG) { throw "Missing learning module. Is a requirement of easeljs-learning"; } else { throw "No learning"; } } //Provide convenience handling of stage off click progress events var display = this.display; if (display) { var stage = display.stage; if (stage) { onStageMouseDown = onStageMouseDown.bind(this); onStageMouseMove = onStageMouseMove.bind(this); stage.addEventListener("stagemousedown", onStageMouseDown); stage.addEventListener("stagemousemove", onStageMouseMove); } } done(); }; /** * Fires event whenever the mouse is moved * @method onStateMouseMove * @private * @param {createjs.MouseEvent} ev The mouse event */ var onStageMouseMove = function(ev) { if (ev.pointerID === this._lastPointerID) { _currentPosition.x = ev.stageX; _currentPosition.y = ev.stageY; } }; /** * Fires OffClick event if click on unhandled object * @method onStageMouseDown * @private * @param {createjs.MouseEvent} ev The mouse event */ var onStageMouseDown = function(ev) { // Keep track of the last pointer ID // this allows us to remember the last position this._lastPointerID = ev.pointerID; var stage = ev.target; var target = stage._getObjectsUnderPoint(ev.stageX, ev.stageY, null, true); var foundListener = false; if (target) { while (target && target != stage) { if (target.hasEventListener("mousedown") || target.hasEventListener("click")) { foundListener = true; break; } target = target.parent; } } if (!foundListener) //no interactive objects found { //duplicate the array of optional offClick parameters var arr = this.offClickParams.slice(0); //make sure we are sending the default parameter (position) //as the first parameter arr.unshift(this.normalizePosition(ev.stageX, ev.stageY)); //send the entire array of parameters if (this.learning.offClick) { this.learning.offClick.apply(this, arr); } else if (DEBUG && Debug) { Debug.info("Learning doesn't have an offClick event"); } } }; // Destroy the animator plugin.teardown = function() { //Remove stage listener var display = this.display; if (display && display.stage) { var stage = display.stage; if (stage) { stage.removeEventListener("stagemousedown", onStageMouseDown); stage.removeEventListener("stagemousemove", onStageMouseMove); } } this.offClickParams = null; }; }());