Modularise handlers.
This commit is contained in:
@@ -0,0 +1,170 @@
|
||||
/* Copyright (c) 2015 Hyunje Alex Jun and other contributors
|
||||
* Licensed under the MIT License
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var instances = require('../instances')
|
||||
, updateGeometry = require('../update');
|
||||
|
||||
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) {
|
||||
element.scrollTop = element.scrollTop - differenceY;
|
||||
element.scrollLeft = 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 (!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 (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);
|
||||
}
|
||||
|
||||
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, supportsTouch, supportsIePointer) {
|
||||
var i = instances.get(element);
|
||||
bindTouchHandler(element, i, supportsTouch, supportsIePointer);
|
||||
};
|
||||
Reference in New Issue
Block a user