UNPKG

decks

Version:

JavaScript UI library for viewing collections of items.

183 lines (158 loc) 5.5 kB
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;