import * as support from './_support'; import * as options from './_defaults'; import * as settings from './_settings'; import { percentage2number } from './_helpers'; import { extend } from '../helpers'; var DragEvents = /** @class */ (function () { /** * Create the gestures. * @param {HTMLElement} surface The surface for the gesture. * @param {object} area Restriction where on the surface the gesture can be started. * @param {object} treshold Treshold for the gestures. */ function DragEvents(surface, area, treshold) { this.surface = surface; this.area = extend(area, options.area); this.treshold = extend(treshold, options.treshold); // Set the mouse/touch events. if (!this.surface['mmHasDragEvents']) { this.surface.addEventListener(support.touch ? 'touchstart' : 'mousedown', this.start.bind(this)); this.surface.addEventListener(support.touch ? 'touchend' : 'mouseup', this.stop.bind(this)); this.surface.addEventListener(support.touch ? 'touchleave' : 'mouseleave', this.stop.bind(this)); this.surface.addEventListener(support.touch ? 'touchmove' : 'mousemove', this.move.bind(this)); } this.surface['mmHasDragEvents'] = true; } /** * Starting the touch gesture. * @param {Event} event The touch event. */ DragEvents.prototype.start = function (event) { this.currentPosition = { x: event.touches ? event.touches[0].pageX : event.pageX || 0, y: event.touches ? event.touches[0].pageY : event.pageY || 0 }; /** The widht of the surface. */ var width = this.surface.clientWidth; /** The height of the surface. */ var height = this.surface.clientHeight; // Check if the gesture started below the area.top. var top = percentage2number(this.area.top, height); if (typeof top == 'number') { if (this.currentPosition.y < top) { return; } } // Check if the gesture started before the area.right. var right = percentage2number(this.area.right, width); if (typeof right == 'number') { right = width - right; if (this.currentPosition.x > right) { return; } } // Check if the gesture started above the area.bottom. var bottom = percentage2number(this.area.bottom, height); if (typeof bottom == 'number') { bottom = height - bottom; if (this.currentPosition.y > bottom) { return; } } // Check if the gesture started after the area.left. var left = percentage2number(this.area.left, width); if (typeof left == 'number') { if (this.currentPosition.x < left) { return; } } // Store the start x- and y-position. this.startPosition = { x: this.currentPosition.x, y: this.currentPosition.y }; // Set the state of the gesture to "watching". this.state = settings.state.watching; }; /** * Stopping the touch gesture. * @param {Event} event The touch event. */ DragEvents.prototype.stop = function (event) { // Dispatch the "dragEnd" events. if (this.state == settings.state.dragging) { /** The direction. */ var dragDirection = this._dragDirection(); /** The event information. */ var detail = this._eventDetail(dragDirection); this._dispatchEvents('drag*End', detail); // Dispatch the "swipe" events. if (Math.abs(this.movement[this.axis]) > this.treshold.swipe) { /** The direction. */ var swipeDirection = this._swipeDirection(); detail.direction = swipeDirection; this._dispatchEvents('swipe*', detail); } } // Set the state of the gesture to "inactive". this.state = settings.state.inactive; }; /** * Doing the touch gesture. * @param {Event} event The touch event. */ DragEvents.prototype.move = function (event) { switch (this.state) { case settings.state.watching: case settings.state.dragging: var position = { x: event.changedTouches ? event.touches[0].pageX : event.pageX || 0, y: event.changedTouches ? event.touches[0].pageY : event.pageY || 0 }; this.movement = { x: position.x - this.currentPosition.x, y: position.y - this.currentPosition.y }; this.distance = { x: position.x - this.startPosition.x, y: position.y - this.startPosition.y }; this.currentPosition = { x: position.x, y: position.y }; this.axis = Math.abs(this.distance.x) > Math.abs(this.distance.y) ? 'x' : 'y'; /** The direction. */ var dragDirection = this._dragDirection(); /** The event information. */ var detail = this._eventDetail(dragDirection); // Watching for the gesture to go past the treshold. if (this.state == settings.state.watching) { if (Math.abs(this.distance[this.axis]) > this.treshold.start) { this._dispatchEvents('drag*Start', detail); // Set the state of the gesture to "inactive". this.state = settings.state.dragging; } } // Dispatch the "drag" events. if (this.state == settings.state.dragging) { this._dispatchEvents('drag*Move', detail); } break; } }; /** * Get the event details. * @param {string} direction Direction for the event (up, right, down, left). * @return {object} The event details. */ DragEvents.prototype._eventDetail = function (direction) { var distX = this.distance.x; var distY = this.distance.y; if (this.axis == 'x') { distX -= distX > 0 ? this.treshold.start : 0 - this.treshold.start; } if (this.axis == 'y') { distY -= distY > 0 ? this.treshold.start : 0 - this.treshold.start; } return { axis: this.axis, direction: direction, movementX: this.movement.x, movementY: this.movement.y, distanceX: distX, distanceY: distY }; }; /** * Dispatch the events * @param {string} eventName The name for the events to dispatch. * @param {object} detail The event details. */ DragEvents.prototype._dispatchEvents = function (eventName, detail) { /** General event, e.g. "drag" */ var event = new CustomEvent(eventName.replace('*', ''), { detail: detail }); this.surface.dispatchEvent(event); /** Axis event, e.g. "dragX" */ var axis = new CustomEvent(eventName.replace('*', this.axis.toUpperCase()), { detail: detail }); this.surface.dispatchEvent(axis); /** Direction event, e.g. "dragLeft" */ var direction = new CustomEvent(eventName.replace('*', detail.direction), { detail: detail }); this.surface.dispatchEvent(direction); }; /** * Get the dragging direction. * @return {string} The direction in which the user is dragging. */ DragEvents.prototype._dragDirection = function () { return settings.directionNames[this.axis][this.distance[this.axis] > 0 ? 0 : 1]; }; /** * Get the dragging direction. * @return {string} The direction in which the user is dragging. */ DragEvents.prototype._swipeDirection = function () { return settings.directionNames[this.axis][this.movement[this.axis] > 0 ? 0 : 1]; }; return DragEvents; }()); export default DragEvents;