@syncfusion/ej2-base
Version:
A common package of Essential JS 2 base libraries, methods and class definitions
353 lines (352 loc) • 14.4 kB
JavaScript
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
/* eslint-disable @typescript-eslint/no-explicit-any */
import { extend } from './util';
import { Property, Complex, NotifyPropertyChanges, Event } from './notify-property-change';
import { Browser } from './browser';
import { Base } from './base';
import { ChildProperty } from './child-property';
import { EventHandler } from './event-handler';
/**
* SwipeSettings is a framework module that provides support to handle swipe event like swipe up, swipe right, etc..,
*/
var SwipeSettings = /** @class */ (function (_super) {
__extends(SwipeSettings, _super);
function SwipeSettings() {
return _super !== null && _super.apply(this, arguments) || this;
}
__decorate([
Property(50)
], SwipeSettings.prototype, "swipeThresholdDistance", void 0);
return SwipeSettings;
}(ChildProperty));
export { SwipeSettings };
var swipeRegex = /(Up|Down)/;
/**
* Touch class provides support to handle the touch event like tap, double tap, tap hold, etc..,
* ```typescript
* let node: HTMLElement;
* let touchObj: Touch = new Touch({
* element: node,
* tap: function (e) {
* // tap handler function code
* }
* tapHold: function (e) {
* // tap hold handler function code
* }
* scroll: function (e) {
* // scroll handler function code
* }
* swipe: function (e) {
* // swipe handler function code
* }
* });
* ```
*/
var Touch = /** @class */ (function (_super) {
__extends(Touch, _super);
/* End-Properties */
function Touch(element, options) {
var _this = _super.call(this, options, element) || this;
_this.touchAction = true;
_this.tapCount = 0;
/**
*
* @param {MouseEventArgs | TouchEventArgs} evt ?
* @returns {void} ?
*/
_this.startEvent = function (evt) {
if (_this.touchAction === true) {
var point = _this.updateChangeTouches(evt);
if (evt.changedTouches !== undefined) {
_this.touchAction = false;
}
_this.isTouchMoved = false;
_this.movedDirection = '';
_this.startPoint = _this.lastMovedPoint = { clientX: point.clientX, clientY: point.clientY };
_this.startEventData = point;
_this.hScrollLocked = _this.vScrollLocked = false;
_this.tStampStart = Date.now();
_this.timeOutTapHold = setTimeout(function () { _this.tapHoldEvent(evt); }, _this.tapHoldThreshold);
EventHandler.add(_this.element, Browser.touchMoveEvent, _this.moveEvent, _this);
EventHandler.add(_this.element, Browser.touchEndEvent, _this.endEvent, _this);
EventHandler.add(_this.element, Browser.touchCancelEvent, _this.cancelEvent, _this);
}
};
/**
*
* @param {MouseEventArgs | TouchEventArgs} evt ?
* @returns {void} ?
*/
_this.moveEvent = function (evt) {
var point = _this.updateChangeTouches(evt);
_this.movedPoint = point;
_this.isTouchMoved = !(point.clientX === _this.startPoint.clientX && point.clientY === _this.startPoint.clientY);
var eScrollArgs = {};
if (_this.isTouchMoved) {
clearTimeout(_this.timeOutTapHold);
_this.calcScrollPoints(evt);
var scrollArg = {
startEvents: _this.startEventData,
originalEvent: evt, startX: _this.startPoint.clientX,
startY: _this.startPoint.clientY, distanceX: _this.distanceX,
distanceY: _this.distanceY, scrollDirection: _this.scrollDirection,
velocity: _this.getVelocity(point)
};
eScrollArgs = extend(eScrollArgs, {}, scrollArg);
_this.trigger('scroll', eScrollArgs);
_this.lastMovedPoint = { clientX: point.clientX, clientY: point.clientY };
}
};
/**
*
* @param {MouseEventArgs | TouchEventArgs} evt ?
* @returns {void} ?
*/
_this.cancelEvent = function (evt) {
clearTimeout(_this.timeOutTapHold);
clearTimeout(_this.timeOutTap);
_this.tapCount = 0;
_this.swipeFn(evt);
EventHandler.remove(_this.element, Browser.touchCancelEvent, _this.cancelEvent);
};
/**
*
* @param {MouseEventArgs | TouchEventArgs} evt ?
* @returns {void} ?
*/
_this.endEvent = function (evt) {
_this.swipeFn(evt);
if (!_this.isTouchMoved) {
if (typeof _this.tap === 'function') {
_this.trigger('tap', { originalEvent: evt, tapCount: ++_this.tapCount });
_this.timeOutTap = setTimeout(function () {
_this.tapCount = 0;
}, _this.tapThreshold);
}
}
_this.modeclear();
};
/**
*
* @param {MouseEventArgs | TouchEventArgs} evt ?
* @returns {void} ?
*/
_this.swipeFn = function (evt) {
clearTimeout(_this.timeOutTapHold);
clearTimeout(_this.timeOutTap);
var point = _this.updateChangeTouches(evt);
var diffX = point.clientX - _this.startPoint.clientX;
var diffY = point.clientY - _this.startPoint.clientY;
diffX = Math.floor(diffX < 0 ? -1 * diffX : diffX);
diffY = Math.floor(diffY < 0 ? -1 * diffY : diffX);
_this.isTouchMoved = diffX > 1 || diffY > 1;
var isFirefox = (/Firefox/).test(Browser.userAgent);
if (isFirefox && point.clientX === 0 && point.clientY === 0 && evt.type === 'mouseup') {
_this.isTouchMoved = false;
}
_this.endPoint = point;
_this.calcPoints(evt);
var swipeArgs = {
originalEvent: evt,
startEvents: _this.startEventData,
startX: _this.startPoint.clientX,
startY: _this.startPoint.clientY,
distanceX: _this.distanceX, distanceY: _this.distanceY, swipeDirection: _this.movedDirection,
velocity: _this.getVelocity(point)
};
if (_this.isTouchMoved) {
var tDistance = _this.swipeSettings.swipeThresholdDistance;
var eSwipeArgs = extend(undefined, _this.defaultArgs, swipeArgs);
var canTrigger = false;
var ele = _this.element;
var scrollBool = _this.isScrollable(ele);
var moved = swipeRegex.test(_this.movedDirection);
if ((tDistance < _this.distanceX && !moved) || (tDistance < _this.distanceY && moved)) {
if (!scrollBool) {
canTrigger = true;
}
else {
canTrigger = _this.checkSwipe(ele, moved);
}
}
if (canTrigger) {
_this.trigger('swipe', eSwipeArgs);
}
}
_this.modeclear();
};
_this.modeclear = function () {
_this.modeClear = setTimeout(function () {
_this.touchAction = true;
}, (typeof _this.tap !== 'function' ? 0 : 20));
_this.lastTapTime = new Date().getTime();
EventHandler.remove(_this.element, Browser.touchMoveEvent, _this.moveEvent);
EventHandler.remove(_this.element, Browser.touchEndEvent, _this.endEvent);
EventHandler.remove(_this.element, Browser.touchCancelEvent, _this.cancelEvent);
};
_this.bind();
return _this;
}
// triggers when property changed
/**
*
* @private
* @param {TouchModel} newProp ?
* @param {TouchModel} oldProp ?
* @returns {void} ?
*/
Touch.prototype.onPropertyChanged = function (newProp, oldProp) {
//No Code to handle
};
Touch.prototype.bind = function () {
this.wireEvents();
if (Browser.isIE) {
this.element.classList.add('e-block-touch');
}
};
/**
* To destroy the touch instance.
*
* @returns {void}
*/
Touch.prototype.destroy = function () {
this.unwireEvents();
_super.prototype.destroy.call(this);
};
// Need to changes the event binding once we updated the event handler.
Touch.prototype.wireEvents = function () {
EventHandler.add(this.element, Browser.touchStartEvent, this.startEvent, this);
};
Touch.prototype.unwireEvents = function () {
EventHandler.remove(this.element, Browser.touchStartEvent, this.startEvent);
};
/**
* Returns module name as touch
*
* @returns {string} ?
* @private
*/
Touch.prototype.getModuleName = function () {
return 'touch';
};
/**
* Returns if the HTML element is Scrollable.
*
* @param {HTMLElement} element - HTML Element to check if Scrollable.
* @returns {boolean} ?
*/
Touch.prototype.isScrollable = function (element) {
var eleStyle = getComputedStyle(element);
var style = eleStyle.overflow + eleStyle.overflowX + eleStyle.overflowY;
if ((/(auto|scroll)/).test(style)) {
return true;
}
return false;
};
/**
*
* @param {MouseEventArgs | TouchEventArgs} evt ?
* @returns {void} ?
*/
Touch.prototype.tapHoldEvent = function (evt) {
this.tapCount = 0;
this.touchAction = true;
EventHandler.remove(this.element, Browser.touchMoveEvent, this.moveEvent);
EventHandler.remove(this.element, Browser.touchEndEvent, this.endEvent);
var eTapArgs = { originalEvent: evt };
this.trigger('tapHold', eTapArgs);
EventHandler.remove(this.element, Browser.touchCancelEvent, this.cancelEvent);
};
Touch.prototype.calcPoints = function (evt) {
var point = this.updateChangeTouches(evt);
this.defaultArgs = { originalEvent: evt };
this.distanceX = Math.abs((Math.abs(point.clientX) - Math.abs(this.startPoint.clientX)));
this.distanceY = Math.abs((Math.abs(point.clientY) - Math.abs(this.startPoint.clientY)));
if (this.distanceX > this.distanceY) {
this.movedDirection = (point.clientX > this.startPoint.clientX) ? 'Right' : 'Left';
}
else {
this.movedDirection = (point.clientY < this.startPoint.clientY) ? 'Up' : 'Down';
}
};
Touch.prototype.calcScrollPoints = function (evt) {
var point = this.updateChangeTouches(evt);
this.defaultArgs = { originalEvent: evt };
this.distanceX = Math.abs((Math.abs(point.clientX) - Math.abs(this.lastMovedPoint.clientX)));
this.distanceY = Math.abs((Math.abs(point.clientY) - Math.abs(this.lastMovedPoint.clientY)));
if ((this.distanceX > this.distanceY || this.hScrollLocked === true) && this.vScrollLocked === false) {
this.scrollDirection = (point.clientX > this.lastMovedPoint.clientX) ? 'Right' : 'Left';
this.hScrollLocked = true;
}
else {
this.scrollDirection = (point.clientY < this.lastMovedPoint.clientY) ? 'Up' : 'Down';
this.vScrollLocked = true;
}
};
Touch.prototype.getVelocity = function (pnt) {
var newX = pnt.clientX;
var newY = pnt.clientY;
var newT = Date.now();
var xDist = newX - this.startPoint.clientX;
var yDist = newY - this.startPoint.clientX;
var interval = newT - this.tStampStart;
return Math.sqrt(xDist * xDist + yDist * yDist) / interval;
};
Touch.prototype.checkSwipe = function (ele, flag) {
var keys = ['scroll', 'offset'];
var temp = flag ? ['Height', 'Top'] : ['Width', 'Left'];
if ((ele[keys[0] + temp[0]] <= ele[keys[1] + temp[0]])) {
return true;
}
return (ele[keys[0] + temp[1]] === 0) ||
(ele[keys[1] + temp[0]] + ele[keys[0] + temp[1]] >= ele[keys[0] + temp[0]]);
};
Touch.prototype.updateChangeTouches = function (evt) {
var point = evt.changedTouches && evt.changedTouches.length !== 0 ? evt.changedTouches[0] : evt;
return point;
};
__decorate([
Event()
], Touch.prototype, "tap", void 0);
__decorate([
Event()
], Touch.prototype, "tapHold", void 0);
__decorate([
Event()
], Touch.prototype, "swipe", void 0);
__decorate([
Event()
], Touch.prototype, "scroll", void 0);
__decorate([
Property(350)
], Touch.prototype, "tapThreshold", void 0);
__decorate([
Property(750)
], Touch.prototype, "tapHoldThreshold", void 0);
__decorate([
Complex({}, SwipeSettings)
], Touch.prototype, "swipeSettings", void 0);
Touch = __decorate([
NotifyPropertyChanges
], Touch);
return Touch;
}(Base));
export { Touch };