mirror of
https://github.com/jellyfin/jellyfin-web.git
synced 2024-11-17 19:08:18 -07:00
165 lines
5.2 KiB
JavaScript
165 lines
5.2 KiB
JavaScript
import dom from '../scripts/dom';
|
|
import { Events } from 'jellyfin-apiclient';
|
|
|
|
function getTouches(e) {
|
|
return e.changedTouches || e.targetTouches || e.touches;
|
|
}
|
|
|
|
class TouchHelper {
|
|
constructor(elem, options) {
|
|
options = options || {};
|
|
let touchTarget;
|
|
let touchStartX;
|
|
let touchStartY;
|
|
let lastDeltaX;
|
|
let lastDeltaY;
|
|
let thresholdYMet;
|
|
const self = this;
|
|
|
|
const swipeXThreshold = options.swipeXThreshold || 50;
|
|
const swipeYThreshold = options.swipeYThreshold || 50;
|
|
const swipeXMaxY = 30;
|
|
|
|
const excludeTagNames = options.ignoreTagNames || [];
|
|
|
|
const touchStart = function (e) {
|
|
const touch = getTouches(e)[0];
|
|
touchTarget = null;
|
|
touchStartX = 0;
|
|
touchStartY = 0;
|
|
lastDeltaX = null;
|
|
lastDeltaY = null;
|
|
thresholdYMet = false;
|
|
|
|
if (touch) {
|
|
const currentTouchTarget = touch.target;
|
|
|
|
if (dom.parentWithTag(currentTouchTarget, excludeTagNames)) {
|
|
return;
|
|
}
|
|
|
|
touchTarget = currentTouchTarget;
|
|
touchStartX = touch.clientX;
|
|
touchStartY = touch.clientY;
|
|
}
|
|
};
|
|
|
|
const touchEnd = function (e) {
|
|
const isTouchMove = e.type === 'touchmove';
|
|
|
|
if (touchTarget) {
|
|
const touch = getTouches(e)[0];
|
|
|
|
let deltaX;
|
|
let deltaY;
|
|
|
|
let clientX;
|
|
let clientY;
|
|
|
|
if (touch) {
|
|
clientX = touch.clientX || 0;
|
|
clientY = touch.clientY || 0;
|
|
deltaX = clientX - (touchStartX || 0);
|
|
deltaY = clientY - (touchStartY || 0);
|
|
} else {
|
|
deltaX = 0;
|
|
deltaY = 0;
|
|
}
|
|
|
|
const currentDeltaX = lastDeltaX == null ? deltaX : (deltaX - lastDeltaX);
|
|
const currentDeltaY = lastDeltaY == null ? deltaY : (deltaY - lastDeltaY);
|
|
|
|
lastDeltaX = deltaX;
|
|
lastDeltaY = deltaY;
|
|
|
|
if (deltaX > swipeXThreshold && Math.abs(deltaY) < swipeXMaxY) {
|
|
Events.trigger(self, 'swiperight', [touchTarget]);
|
|
} else if (deltaX < (0 - swipeXThreshold) && Math.abs(deltaY) < swipeXMaxY) {
|
|
Events.trigger(self, 'swipeleft', [touchTarget]);
|
|
} else if ((deltaY < (0 - swipeYThreshold) || thresholdYMet) && Math.abs(deltaX) < swipeXMaxY) {
|
|
thresholdYMet = true;
|
|
|
|
Events.trigger(self, 'swipeup', [touchTarget, {
|
|
deltaY: deltaY,
|
|
deltaX: deltaX,
|
|
clientX: clientX,
|
|
clientY: clientY,
|
|
currentDeltaX: currentDeltaX,
|
|
currentDeltaY: currentDeltaY
|
|
}]);
|
|
} else if ((deltaY > swipeYThreshold || thresholdYMet) && Math.abs(deltaX) < swipeXMaxY) {
|
|
thresholdYMet = true;
|
|
|
|
Events.trigger(self, 'swipedown', [touchTarget, {
|
|
deltaY: deltaY,
|
|
deltaX: deltaX,
|
|
clientX: clientX,
|
|
clientY: clientY,
|
|
currentDeltaX: currentDeltaX,
|
|
currentDeltaY: currentDeltaY
|
|
}]);
|
|
}
|
|
|
|
if (isTouchMove && options.preventDefaultOnMove) {
|
|
e.preventDefault();
|
|
}
|
|
}
|
|
|
|
if (!isTouchMove) {
|
|
touchTarget = null;
|
|
touchStartX = 0;
|
|
touchStartY = 0;
|
|
lastDeltaX = null;
|
|
lastDeltaY = null;
|
|
thresholdYMet = false;
|
|
}
|
|
};
|
|
|
|
this.touchStart = touchStart;
|
|
this.touchEnd = touchEnd;
|
|
|
|
dom.addEventListener(elem, 'touchstart', touchStart, {
|
|
passive: true
|
|
});
|
|
if (options.triggerOnMove) {
|
|
dom.addEventListener(elem, 'touchmove', touchEnd, {
|
|
passive: !options.preventDefaultOnMove
|
|
});
|
|
}
|
|
dom.addEventListener(elem, 'touchend', touchEnd, {
|
|
passive: true
|
|
});
|
|
dom.addEventListener(elem, 'touchcancel', touchEnd, {
|
|
passive: true
|
|
});
|
|
}
|
|
destroy() {
|
|
const elem = this.elem;
|
|
|
|
if (elem) {
|
|
const touchStart = this.touchStart;
|
|
const touchEnd = this.touchEnd;
|
|
|
|
dom.removeEventListener(elem, 'touchstart', touchStart, {
|
|
passive: true
|
|
});
|
|
dom.removeEventListener(elem, 'touchmove', touchEnd, {
|
|
passive: true
|
|
});
|
|
dom.removeEventListener(elem, 'touchend', touchEnd, {
|
|
passive: true
|
|
});
|
|
dom.removeEventListener(elem, 'touchcancel', touchEnd, {
|
|
passive: true
|
|
});
|
|
}
|
|
|
|
this.touchStart = null;
|
|
this.touchEnd = null;
|
|
|
|
this.elem = null;
|
|
}
|
|
}
|
|
|
|
export default TouchHelper;
|