var _ = require("lodash");
var Hammer = require("hammerjs");
var GestureEmitter = require("./gestureemitter");
var DecksEvent = require("../events/decksevent");
/**
* Class that emits or provides support for pan gestures/events.
*
* @class
* @extends GestureEmitter
* @param {!Object} options - Additional options
* @param {?(Emitter|Object)} [options.emitter={}] - Emitter instance or options on which to emit events
* @param {!Element} options.element - Element for which to bind events
* @param {!Hammer} options.hammer - Hammer instance for the element (required by base class)
* @param {?boolean} [options.enabled=false] - Whether to enable this emitter
* @param {?boolean} [options.horizontal=false] - Whether to monitor horizontal pan gestures.
* @param {?boolean} [options.vertical=true] - Whether to monitor vertical pan gestures.
* @param {?number} [options.threshold=0] - Threshold distance before pan gestures are detected.
*/
function PanEmitter(options) {
if (!(this instanceof PanEmitter)) {
return new PanEmitter(options);
}
options = _.merge({}, this.defaultOptions, options);
GestureEmitter.call(this, options);
/** Whether to emit events for horizontal pan gestures. */
this.horizontal = !!options.horizontal;
/** Whether to emit events for horizontal pan gestures. */
this.vertical = !!options.vertical;
/** Pixel distance before pan events are emitted. */
this.threshold = options.threshold || 0;
if (options.horizontal && options.vertical) {
/** Hammer direction enum value to use. */
this.direction = Hammer.DIRECTION_ALL;
} else if (options.horizontal) {
this.direction = Hammer.DIRECTION_HORIZONTAL;
} else {
this.direction = Hammer.DIRECTION_VERTICAL;
}
this.hammer.get("pan").set({
direction: this.direction,
threshold: this.threshold
});
this.bind();
}
PanEmitter.prototype = _.create(GestureEmitter.prototype, /** @lends PanEmitter.prototype */ {
constructor: PanEmitter,
/**
* Default options hash for constructor.
*/
defaultOptions: _.merge({}, GestureEmitter.prototype.defaultOptions, {
horizontal: false,
vertical: true,
threshold: 0
}),
/**
* Returns the map of Hammer.js events to which to bind.
*/
getHammerEvents: function getHammerEvents() {
var map = {
"panstart": "onPanStart",
"panend": "onPanEnd",
"pancancel": "onPanCancel"
};
if (this.horizontal && this.vertical) {
map.panmove = "onPanMove";
} else if (this.horizontal) {
map["panleft panright"] = "onPanX";
} else if (this.vertical) {
map["panup pandown"] = "onPanY";
}
return map;
},
onPanStart: function onPanStart(e) {
/**
* Event for a pan start.
*
* @event PanEmitter#gesture:pan:start
* @type {DecksEvent}
* @property {String} type - the event type string
* @property {PanEmitter} sender - the sender of the event
* @property {*} data - the hammer event object
*/
this.emit(DecksEvent("gesture:pan:start", this, e));
},
/**
* Called when a panmove event is detected by Hammer.js.
*
* @fires PanEmitter#gesture:pan:any
*
* @param e - Hammer event object
* @returns {undefined}
*/
onPanMove: function onPanMove(e) {
// TODO: might want to emit pan:x and pan:y here too (if direction is applicable)
/**
* Event for a pan gesture in any direction.
*
* @event PanEmitter#gesture:pan:any
* @type {DecksEvent}
* @property {String} type - the event type string
* @property {PanEmitter} sender - the sender of the event
* @property {*} data - the hammer event object
* @returns {undefined}
*/
this.emit(DecksEvent("gesture:pan:any", this, e));
},
onPanX: function onPanX(e) {
// TODO: might want to emit pan:any here too
/**
* Event for a pan gesture in the horizontal direction.
*
* @event PanEmitter#gesture:pan:x
* @type {DecksEvent}
* @property {String} type - the event type string
* @property {PanEmitter} sender - the sender of the event
* @property {*} data - the hammer event object
*/
this.emit(DecksEvent("gesture:pan:x", this, e));
},
onPanY: function onPanY(e) {
// TODO: might want to emit pan:any here too
/**
* Event for a pan gesture in the vertical direction.
*
* @event PanEmitter#gesture:pan:y
* @type {DecksEvent}
* @property {String} type - the event type string
* @property {PanEmitter} sender - the sender of the event
* @property {*} data - the hammer event object
*/
this.emit(DecksEvent("gesture:pan:y", this, e));
},
onPanEnd: function onPanEnd(e) {
/**
* Event for a pan end.
*
* @event PanEmitter#gesture:pan:end
* @type {DecksEvent}
* @property {String} type - the event type string
* @property {PanEmitter} sender - the sender of the event
* @property {*} data - the hammer event object
*/
this.emit(DecksEvent("gesture:pan:end", this, e));
},
onPanCancel: function onPanCancel(e) {
/**
* Event for a pan cancel.
*
* @event PanEmitter#gesture:pan:cancel
* @type {DecksEvent}
* @property {String} type - the event type string
* @property {PanEmitter} sender - the sender of the event
* @property {*} data - the hammer event object
*/
this.emit(DecksEvent("gesture:pan:cancel", this, e));
}
});
module.exports = PanEmitter;