This repo is archived. You can view files and clone it, but cannot push or open issues or pull requests.
SXS20240115/SRC/iMES_PDA/JSplugins/angular-swipe/angular-swipe.js
2024-01-24 16:47:50 +08:00

221 lines
5.9 KiB
JavaScript

(function(window, angular, undefined) {
'use strict';
/* global -ngSwipe */
var ngSwipe = angular.module('swipe', []);
ngSwipe.factory('swipe', [ function() {
var MOVE_BUFFER_RADIUS = 40;
var MAX_RATIO = 0.3;
var POINTER_EVENTS = {
'mouse': {
start: 'mousedown',
move: 'mousemove',
end: 'mouseup'
},
'touch': {
start: 'touchstart',
move: 'touchmove',
end: 'touchend',
cancel: 'touchcancel'
}
};
function getCoordinates(event) {
var originalEvent = event.originalEvent || event;
var touches = originalEvent.touches && originalEvent.touches.length ? originalEvent.touches : [originalEvent];
var e = (originalEvent.changedTouches && originalEvent.changedTouches[0]) || touches[0];
return {
x: e.clientX,
y: e.clientY
};
}
function getEvents(pointerTypes, eventType) {
var res = [];
angular.forEach(pointerTypes, function(pointerType) {
var eventName = POINTER_EVENTS[pointerType][eventType];
if (eventName) {
res.push(eventName);
}
});
return res.join(' ');
}
return {
bind: function(element, eventHandlers, pointerTypes) {
// Absolute total movement
var totalX, totalY;
// Coordinates of the start position.
var startCoords;
var lastPos;
// Whether a swipe is active.
var active = false;
// Decide where we are going
var isDecided = false;
var isVertical = true;
pointerTypes = pointerTypes || ['mouse', 'touch'];
element.on(getEvents(pointerTypes, 'start'), function(event) {
startCoords = getCoordinates(event);
active = true;
totalX = 0;
totalY = 0;
isDecided = false;
isVertical = true;
lastPos = startCoords;
eventHandlers['start'] && eventHandlers['start'](startCoords, event);
});
element.on(getEvents(pointerTypes, 'cancel'), function(event) {
active = false;
eventHandlers['cancel'] && eventHandlers['cancel'](event);
});
element.on(getEvents(pointerTypes, 'move'), function(event) {
if (! active) {
return;
}
if (! startCoords) {
return;
}
var coords = getCoordinates(event);
totalX += Math.abs(coords.x - lastPos.x);
totalY += Math.abs(coords.y - lastPos.y);
lastPos = coords;
if (totalX < MOVE_BUFFER_RADIUS && totalY < MOVE_BUFFER_RADIUS) {
return;
} else {
if (! isDecided){
var deltaX, deltaY, ratio;
deltaX = Math.abs(coords.x - startCoords.x);
deltaY = Math.abs(coords.y - startCoords.y);
ratio = deltaY / deltaX;
if (ratio < MAX_RATIO){
event.preventDefault();
isVertical = false;
} else {
isVertical = true;
}
isDecided = true;
}
}
event.isVertical = isVertical;
eventHandlers['move'] && eventHandlers['move'](coords, event);
});
element.on(getEvents(pointerTypes, 'end'), function(event) {
if (! active){
return;
}
event.isVertical = isVertical;
active = false;
eventHandlers['end'] && eventHandlers['end'](getCoordinates(event), event);
});
}
};
}]);
function makeSwipeDirective(directiveName, direction, axis, eventName) {
ngSwipe.directive(directiveName, ['$parse', 'swipe', function($parse, swipe) {
var MAX_OTHER_AXIS_DISTANCE = 75;
var MAX_RATIO = 0.3;
var MIN_DISTANCE = 30;
return function(scope, element, attr) {
var swipeHandler = $parse(attr[directiveName]);
var startCoords, valid;
function validSwipe(coords) {
if (! startCoords || ! valid){
return false;
}
var deltaY = (coords.y - startCoords.y) * direction;
var deltaX = (coords.x - startCoords.x) * direction;
if (! axis){ // horizontal swipe
return Math.abs(deltaY) < MAX_OTHER_AXIS_DISTANCE &&
deltaX > 0 &&
deltaX > MIN_DISTANCE &&
Math.abs(deltaY) / deltaX < MAX_RATIO;
} else { // vertical swipe
return Math.abs(deltaX) < MAX_OTHER_AXIS_DISTANCE &&
deltaY > 0 &&
deltaY > MIN_DISTANCE &&
Math.abs(deltaX) / deltaY < MAX_RATIO;
}
}
var pointerTypes = ['touch'];
if (!angular.isDefined(attr['ngSwipeDisableMouse'])) {
pointerTypes.push('mouse');
}
swipe.bind(element, {
'start': function(coords, event) {
var className = event.target.getAttribute('class');
if (axis && (! className || className && className.match('noPreventDefault') === null)) {
event.preventDefault();
}
startCoords = coords;
valid = true;
},
'cancel': function() {
valid = false;
},
'end': function(coords, event) {
if (validSwipe(coords)) {
scope.$apply(function() {
element.triggerHandler(eventName);
swipeHandler(scope, { $event: event });
});
}
}
}, pointerTypes);
};
}]);
}
// avoid conflicts with ngTouch module
try {
angular.module('ngTouch');
} catch(err) {
makeSwipeDirective('ngSwipeLeft', -1, false, 'swipeleft');
makeSwipeDirective('ngSwipeRight', 1, false, 'swiperight');
}
// left is negative x-coordinate, right is positive
makeSwipeDirective('ngSwipeUp', -1, true, 'swipeup');
makeSwipeDirective('ngSwipeDown', 1, true, 'swipedown');
})(window, window.angular);