mirror of https://github.com/friendica/friendica
180 lines
4.9 KiB
JavaScript
180 lines
4.9 KiB
JavaScript
'use strict';
|
|
|
|
var _ = require('../../lib/helper');
|
|
var instances = require('../instances');
|
|
var updateGeometry = require('../update-geometry');
|
|
var updateScroll = require('../update-scroll');
|
|
|
|
function bindTouchHandler(element, i, supportsTouch, supportsIePointer) {
|
|
function shouldPreventDefault(deltaX, deltaY) {
|
|
var scrollTop = element.scrollTop;
|
|
var scrollLeft = element.scrollLeft;
|
|
var magnitudeX = Math.abs(deltaX);
|
|
var magnitudeY = Math.abs(deltaY);
|
|
|
|
if (magnitudeY > magnitudeX) {
|
|
// user is perhaps trying to swipe up/down the page
|
|
|
|
if (((deltaY < 0) && (scrollTop === i.contentHeight - i.containerHeight)) ||
|
|
((deltaY > 0) && (scrollTop === 0))) {
|
|
return !i.settings.swipePropagation;
|
|
}
|
|
} else if (magnitudeX > magnitudeY) {
|
|
// user is perhaps trying to swipe left/right across the page
|
|
|
|
if (((deltaX < 0) && (scrollLeft === i.contentWidth - i.containerWidth)) ||
|
|
((deltaX > 0) && (scrollLeft === 0))) {
|
|
return !i.settings.swipePropagation;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
function applyTouchMove(differenceX, differenceY) {
|
|
updateScroll(element, 'top', element.scrollTop - differenceY);
|
|
updateScroll(element, 'left', element.scrollLeft - differenceX);
|
|
|
|
updateGeometry(element);
|
|
}
|
|
|
|
var startOffset = {};
|
|
var startTime = 0;
|
|
var speed = {};
|
|
var easingLoop = null;
|
|
var inGlobalTouch = false;
|
|
var inLocalTouch = false;
|
|
|
|
function globalTouchStart() {
|
|
inGlobalTouch = true;
|
|
}
|
|
function globalTouchEnd() {
|
|
inGlobalTouch = false;
|
|
}
|
|
|
|
function getTouch(e) {
|
|
if (e.targetTouches) {
|
|
return e.targetTouches[0];
|
|
} else {
|
|
// Maybe IE pointer
|
|
return e;
|
|
}
|
|
}
|
|
function shouldHandle(e) {
|
|
if (e.targetTouches && e.targetTouches.length === 1) {
|
|
return true;
|
|
}
|
|
if (e.pointerType && e.pointerType !== 'mouse' && e.pointerType !== e.MSPOINTER_TYPE_MOUSE) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
function touchStart(e) {
|
|
if (shouldHandle(e)) {
|
|
inLocalTouch = true;
|
|
|
|
var touch = getTouch(e);
|
|
|
|
startOffset.pageX = touch.pageX;
|
|
startOffset.pageY = touch.pageY;
|
|
|
|
startTime = (new Date()).getTime();
|
|
|
|
if (easingLoop !== null) {
|
|
clearInterval(easingLoop);
|
|
}
|
|
|
|
e.stopPropagation();
|
|
}
|
|
}
|
|
function touchMove(e) {
|
|
if (!inLocalTouch && i.settings.swipePropagation) {
|
|
touchStart(e);
|
|
}
|
|
if (!inGlobalTouch && inLocalTouch && shouldHandle(e)) {
|
|
var touch = getTouch(e);
|
|
|
|
var currentOffset = {pageX: touch.pageX, pageY: touch.pageY};
|
|
|
|
var differenceX = currentOffset.pageX - startOffset.pageX;
|
|
var differenceY = currentOffset.pageY - startOffset.pageY;
|
|
|
|
applyTouchMove(differenceX, differenceY);
|
|
startOffset = currentOffset;
|
|
|
|
var currentTime = (new Date()).getTime();
|
|
|
|
var timeGap = currentTime - startTime;
|
|
if (timeGap > 0) {
|
|
speed.x = differenceX / timeGap;
|
|
speed.y = differenceY / timeGap;
|
|
startTime = currentTime;
|
|
}
|
|
|
|
if (shouldPreventDefault(differenceX, differenceY)) {
|
|
e.stopPropagation();
|
|
e.preventDefault();
|
|
}
|
|
}
|
|
}
|
|
function touchEnd() {
|
|
if (!inGlobalTouch && inLocalTouch) {
|
|
inLocalTouch = false;
|
|
|
|
clearInterval(easingLoop);
|
|
easingLoop = setInterval(function () {
|
|
if (!instances.get(element)) {
|
|
clearInterval(easingLoop);
|
|
return;
|
|
}
|
|
|
|
if (!speed.x && !speed.y) {
|
|
clearInterval(easingLoop);
|
|
return;
|
|
}
|
|
|
|
if (Math.abs(speed.x) < 0.01 && Math.abs(speed.y) < 0.01) {
|
|
clearInterval(easingLoop);
|
|
return;
|
|
}
|
|
|
|
applyTouchMove(speed.x * 30, speed.y * 30);
|
|
|
|
speed.x *= 0.8;
|
|
speed.y *= 0.8;
|
|
}, 10);
|
|
}
|
|
}
|
|
|
|
if (supportsTouch) {
|
|
i.event.bind(window, 'touchstart', globalTouchStart);
|
|
i.event.bind(window, 'touchend', globalTouchEnd);
|
|
i.event.bind(element, 'touchstart', touchStart);
|
|
i.event.bind(element, 'touchmove', touchMove);
|
|
i.event.bind(element, 'touchend', touchEnd);
|
|
} else if (supportsIePointer) {
|
|
if (window.PointerEvent) {
|
|
i.event.bind(window, 'pointerdown', globalTouchStart);
|
|
i.event.bind(window, 'pointerup', globalTouchEnd);
|
|
i.event.bind(element, 'pointerdown', touchStart);
|
|
i.event.bind(element, 'pointermove', touchMove);
|
|
i.event.bind(element, 'pointerup', touchEnd);
|
|
} else if (window.MSPointerEvent) {
|
|
i.event.bind(window, 'MSPointerDown', globalTouchStart);
|
|
i.event.bind(window, 'MSPointerUp', globalTouchEnd);
|
|
i.event.bind(element, 'MSPointerDown', touchStart);
|
|
i.event.bind(element, 'MSPointerMove', touchMove);
|
|
i.event.bind(element, 'MSPointerUp', touchEnd);
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = function (element) {
|
|
if (!_.env.supportsTouch && !_.env.supportsIePointer) {
|
|
return;
|
|
}
|
|
|
|
var i = instances.get(element);
|
|
bindTouchHandler(element, i, _.env.supportsTouch, _.env.supportsIePointer);
|
|
};
|