File: src/BB.MouseInput.js
/**
* A module for standardizing mouse events from an HTML5 canvas so that they may be used with
* the event funnel suite of modules.
* <br>
* <i>NOTE: For use with HTML5 canvas only.<i>
* @module BB.MouseInput
*/
define(['./BB'],
function( BB){
'use strict';
/**
* A module for standardizing mouse events from an HTML5 canvas so that they may be used with
* the event funnel suite of modules.
* <br>
* <br>
* <i>Note: For use with HTML5 canvas only.</i>
* @class BB.MouseInput
* @constructor
* @param {HTMLCanvasElement} canvasElement The HTML5 canvas object listening for mouse input.
*/
BB.MouseInput = function(canvasElement) {
if (typeof canvasElement === 'undefined' ||
!(canvasElement instanceof HTMLCanvasElement)) {
throw new Error('BB.MouseInput: An HTML5 canvas object must be supplied as a first parameter.');
}
var self = this;
var movingTimeout = null;
/**
* The current x position.
* @property x
* @type {Number}
* @default 0
*/
this.x = 0;
/**
* The current y position.
* @property y
* @type {Number}
* @default 0
*/
this.y = 0;
/**
* The last clicked x position.
* @property clickX
* @type {Number}
* @default 0
*/
this.clickX = 0;
/**
* The last clicked y position.
* @property clickY
* @type {Number}
* @default 0
*/
this.clickY = 0;
/**
* Time in milliseconds that the mouse has been still before its movement is considering to be finished.
* @property moveDebounce
* @type {Number}
* @default 150
*/
this.moveDebounce = 150;
this._isMoving = false;
this._isDown = false;
/**
* The HTML5 canvas element passed into BB.MouseInput during
* construction.
* @property canvasElem
* @type {Object}
*/
this.canvasElem = canvasElement;
this.canvasElem.addEventListener('mousemove', function(e) {
var mouse = getCanvasMouseCoords(e);
self.x = mouse.x;
self.y = mouse.y;
if (!self.isMoving && self.hasOwnProperty('_moveStartCallback') &&
typeof self._moveStartCallback === 'function') {
self._moveStartCallback(self.x, self.y);
}
self._isMoving = true;
clearTimeout(movingTimeout);
movingTimeout = setTimeout(function(){
if (self.isMoving &&
self.hasOwnProperty('_moveStopCallback') &&
typeof self._moveStartCallback === 'function') {
self._isMoving = false;
self._moveStopCallback(self.x, self.y);
}
}, self.moveDebounce);
});
this.canvasElem.addEventListener('mousedown', function(e){
if (e.button === BB.MouseInput.LEFT_BUTTON) {
self._isDown = true;
if (self.hasOwnProperty('_activeStartCallback') &&
typeof self._activeStartCallback === 'function') {
self._activeStartCallback(self.x, self.y);
}
}
});
this.canvasElem.addEventListener('mouseup', function(e){
if (e.button === BB.MouseInput.LEFT_BUTTON) {
self._isDown = false;
if (self.hasOwnProperty('_activeStopCallback') &&
typeof self._activeStopCallback === 'function') {
self._activeStopCallback(self.x, self.y);
}
}
});
this.canvasElem.addEventListener('click', function(e){
var mouse = getCanvasMouseCoords(e);
self.clickX = mouse.x;
self.clickY = mouse.y;
});
this.canvasElem.addEventListener('mouseleave', function() {
if (self._isDown &&
self.hasOwnProperty('_activeStopCallback') &&
typeof self._activeStopCallback === 'function') {
self._activeStopCallback(self.x, self.y);
}
if (self.isMoving &&
self.hasOwnProperty('_moveStopCallback') &&
typeof self._moveStopCallback === 'function') {
self._moveStopCallback(self.x, self.y);
}
self._isMoving = false;
self._isDown = false;
});
function getCanvasMouseCoords(e) {
var rect = self.canvasElem.getBoundingClientRect();
return {
x: Math.round((e.clientX - rect.left) / (rect.right - rect.left) * self.canvasElem.width),
y: Math.round((e.clientY - rect.top) / (rect.bottom - rect.top) * self.canvasElem.height)
};
}
};
/**
* Utility property that hold's the value of a JavaScript MouseEvent's left mouse button.
* @property LEFT_BUTTON
* @static
* @type {Number}
* @default 0
* @readOnly
*/
BB.MouseInput.LEFT_BUTTON = 0;
/**
* Utility property that hold's the value of a JavaScript MouseEvent's scroll wheel button.
* @property SCROLL_BUTTON
* @static
* @type {Number}
* @default 1
* @readOnly
*/
BB.MouseInput.SCROLL_BUTTON = 1;
/**
* Utility property that hold's the value of a JavaScript MouseEvent's right mouse button.
* @property RIGHT_BUTTON
* @static
* @type {Number}
* @default 2
* @readOnly
*/
BB.MouseInput.RIGHT_BUTTON = 2;
/**
* Holds wether or not the mouse is currently moving. This property is read-only.
* @property isMoving
* @type {Boolean}
* @default false
* @readOnly
*/
Object.defineProperty(BB.MouseInput.prototype, 'isMoving', {
get: function(){
return this._isMoving;
},
set: function(val){
throw new Error('BB.MouseInput.isMoving (setter): BB.MouseInput.isMoving is a read-only property.');
}
});
/**
* Holds wether or not the left mouse button is currently depressed. This property is read-only.
* @property isDown
* @type {Boolean}
* @default false
* @readOnly
*/
Object.defineProperty(BB.MouseInput.prototype, 'isDown', {
get: function(){
return this._isDown;
},
set: function(val){
throw new Error('BB.MouseInput.isDown (setter): BB.MouseInput.isDown is a read-only property.');
}
});
BB.MouseInput.prototype.update = function() {
if (this.isMoving &&
this.hasOwnProperty('_moveCallback') &&
typeof this._moveCallback === 'function') {
this._moveCallback(this.x, this.y);
}
};
return BB.MouseInput;
});