File: src/BB.Pointer.js
// A module for funneling in and standardizing pointer-like events
// like mouse, touch, computer-vision detected hands, etc...
// It has basic properties like x, y, isMoving and if the eventModule
// that is passed into its update() has a selection interface (like the
// click on a mouse), then it also has an isDown property.
// Note: This module is for use with HTML5 canvas only.
/**
* A module for funneling in and standardizing basic pointer-like interfaces
* like mouse and touch.
* @module BB.Pointer
*/
define(['./BB', './BB.MouseInput'],
function( BB, MouseInput){
'use strict';
BB.MouseInput = MouseInput;
//NOTE: called inside BB.Pointer using .call()
//to bind this to BB.Pointer instance
function bindEventsToControllerModule() {
/*jshint validthis: true */
// the BBMouseInput module uses event listeners attatched to it's
// HTML5 canvas to fire these callbacks directly, so pass them along.
if (this.controllerModule instanceof BB.MouseInput) {
this.controllerModule._activeStartCallback = this._activeStartCallback;
this.controllerModule._activeStopCallback = this._activeStopCallback;
this.controllerModule._moveStartCallback = this._moveStartCallback;
this.controllerModule._moveStopCallback = this._moveStopCallback;
this.controllerModule._moveCallback = this._moveCallback;
}
}
/**
* A module for funneling in and standardizing basic pointer-like interfaces
* like mouse and touch.
* @class BB.Pointer
* @param {Object} controllerModule The input module you would like to control
* this pointer with.
* @constructor
*/
BB.Pointer = function(controllerModule) {
if (typeof controllerModule === "undefined") {
throw new Error('BB.Pointer: controllerModule parameter is missing from the BB.Pointer constructor.');
} else if (! (controllerModule instanceof BB.MouseInput)) {
this.controllerModule = null;
throw new Error("BB.Pointer.update: controllerModule is not a supported object type.");
}
this.controllerModule = controllerModule;
/**
* The pointer's current x position as supplied by the eventModule in BB.Pointer.update(...).
* @property x
* @type {Number}
* @default undefined
*/
this.x = null;
/**
* The pointer's current y position as supplied by the eventModule in BB.Pointer.update(...).
* @property y
* @type {Number}
* @default undefined
*/
this.y = null;
/**
* A variable holding wether or not the event module controlling this
* pointer object (via BB.Pointer.update(...)) is moving
* @property isMoving
* @type {Boolean}
* @default false
*/
this.isMoving = false;
/**
* A variable holding wether or not the selection interface (i.e. mouse
* button, etc...) controlling this pointer object (via
* BB.Pointer.update(...)) is active.
* @property isDown
* @type {Boolean}
* @default false
*/
this.isDown = false;
/**
* Does the selection interface controlling this pointer have a
* selection interface (like a button)?
* @property hasSelectionInterface
* @type {Boolean}
* @default false
*/
this.hasSelectionInterface = false;
this._activeStartCallback = null;
this._activeStopCallback = null;
this._moveStartCallback = null;
this._moveStopCallback = null;
this._moveCallback = null;
};
Object.defineProperty(BB.Pointer.prototype, "controllerModule", {
get: function(){
return this._controllerModule;
},
set: function(val){
this._controllerModule = val;
// rebind the event callbacks in case this is
// a new controller module
bindEventsToControllerModule.call(this);
}
});
/**
* Update the pointer using the controllerModule. Usually called once per animation frame.
* @method update
* @param {Object} controllerModule
*/
BB.Pointer.prototype.update = function() {
// add a new conditional for each module that pointer supports and then
// update BB.Pointer's internals (x, y, isMoving) in a custom way for
// each type of input (kinect, etc...)
if (this.controllerModule instanceof BB.MouseInput) {
// these assignments are easy for a mouse input object but will take
// more work for other types of modules (i.e. kinect)...
this.x = this.controllerModule.x;
this.y = this.controllerModule.y;
this.isMoving = this.controllerModule.isMoving;
this.isDown = this.controllerModule.isDown;
this.hasSelectionInterface = false;
}
};
/**
* A method used to register "activestart", "activestop", "movestart", "movestop", and "move" events.
* @method on
* @param {String} eventName The event to register callback to.
* "activestart", "activestop", "movestart", and "movestop" are all valid
* events.
* @param {Function} callback The callback to execute once the
* registered event has fired.
*/
BB.Pointer.prototype.on = function(eventName, callback){
// save the callback so that it can be used later in update() if it needs to be
if (eventName == "activestart") this._activeStartCallback = callback;
else if (eventName == "activestop") this._activeStopCallback = callback;
else if (eventName == "movestart") this._moveStartCallback = callback;
else if (eventName == "movestop") this._moveStopCallback = callback;
else if (eventName == "move") this._moveCallback = callback;
else {
throw new Error('BB.Pointer.on: eventName is not a supported event.');
}
if (this._controllerModule === null) {
throw new Error('BB.Pointer.on: pointer has no controller module.' +
' You must first call BB.Pointer.update() to assign this pointer a controller module.');
}
bindEventsToControllerModule.call(this);
};
return BB.Pointer;
});