125 lines
5.5 KiB
JavaScript
125 lines
5.5 KiB
JavaScript
/**
|
|
*
|
|
* @name: mnTouch
|
|
* @version: 1.3.2
|
|
* @description: Ultrafast AngularJS touch events directive (tap, hold and swipe)
|
|
* @author: Alessandro Bellini - ilmente
|
|
* @license: MIT
|
|
*
|
|
*/
|
|
"use strict";
|
|
|
|
angular.module("mn", []).directive("mnTouch", [ "$timeout", function($timeout) {
|
|
var touchEngine = function(scope, element, attrs) {
|
|
scope.$event = {
|
|
name: "",
|
|
isSecure: false,
|
|
isRunning: false,
|
|
target: element[0],
|
|
threshold: !!attrs.threshold ? attrs.threshold : 10,
|
|
holdfor: !!attrs.holdfor ? attrs.holdfor : 500,
|
|
types: {
|
|
start: "mousedown",
|
|
move: "mousemove",
|
|
end: "mouseup",
|
|
cancel: ""
|
|
},
|
|
time: {},
|
|
coords: {},
|
|
events: {},
|
|
directionX: 0,
|
|
directionY: 0,
|
|
offsetX: 0,
|
|
offsetY: 0
|
|
};
|
|
var fn = function(eventName) {
|
|
scope.$event.name = eventName;
|
|
if (!!attrs[eventName]) {
|
|
scope.$eval(attrs[eventName]);
|
|
scope.$apply();
|
|
}
|
|
};
|
|
var getCoords = function(event) {
|
|
return {
|
|
x: event.pageX || 0,
|
|
y: event.pageY || 0
|
|
};
|
|
};
|
|
if (typeof window.ontouchstart !== "undefined" && typeof window.ontouchend !== "undefined" && typeof window.ontouchcancel !== "undefined") {
|
|
scope.$event.types.start = "touchstart";
|
|
scope.$event.types.move = "touchmove";
|
|
scope.$event.types.end = "touchend";
|
|
scope.$event.types.cancel = "touchcancel";
|
|
getCoords = function(event) {
|
|
var coords = !!event && !!event.changedTouches && !!event.changedTouches.length > 0 ? event.changedTouches[0] : {};
|
|
return {
|
|
x: coords.pageX || event.pageX || 0,
|
|
y: coords.pageY || event.pageY || 0
|
|
};
|
|
};
|
|
} else if (window.navigator.pointerEnabled) {
|
|
scope.$event.types.start = "pointerdown";
|
|
scope.$event.types.move = "pointermove";
|
|
scope.$event.types.end = "pointerup";
|
|
} else if (window.navigator.msPointerEnabled) {
|
|
scope.$event.types.start = "MSPointerDown";
|
|
scope.$event.types.move = "MSPointerMove";
|
|
scope.$event.types.end = "MSPointerUp";
|
|
scope.$event.types.cancel = "MSPointerOut";
|
|
}
|
|
if (!!attrs["tap"]) {
|
|
scope.$event.isSecure = false;
|
|
scope.$event.isRunning = false;
|
|
var onStartEvent = function(startEvent) {
|
|
scope.$event.events.start = startEvent;
|
|
scope.$event.coords.start = getCoords(startEvent);
|
|
fn("tap");
|
|
};
|
|
scope.$event.target.addEventListener(scope.$event.types.start, onStartEvent, false);
|
|
} else {
|
|
scope.$event.isSecure = true;
|
|
var holdPromise = null;
|
|
var onStartEvent = function(startEvent) {
|
|
scope.$event.isRunning = true;
|
|
scope.$event.time.start = new Date().getTime();
|
|
scope.$event.events.start = startEvent;
|
|
scope.$event.coords.start = getCoords(startEvent);
|
|
if (!!attrs["hold"]) {
|
|
holdPromise = $timeout(function() {
|
|
onEndEvent(scope.$event.events.move || startEvent);
|
|
}, scope.$event.holdfor, false);
|
|
}
|
|
};
|
|
var onMoveEvent = function(moveEvent) {
|
|
if (scope.$event.isRunning) {
|
|
scope.$event.events.move = moveEvent;
|
|
}
|
|
};
|
|
var onEndEvent = function(endEvent) {
|
|
if (!!holdPromise) $timeout.cancel(holdPromise);
|
|
if (scope.$event.isRunning) {
|
|
scope.$event.isRunning = false;
|
|
scope.$event.time.end = new Date().getTime();
|
|
scope.$event.time.duration = scope.$event.time.end - scope.$event.time.start;
|
|
scope.$event.events.end = endEvent;
|
|
scope.$event.coords.end = getCoords(endEvent);
|
|
scope.$event.directionX = scope.$event.coords.end.x - scope.$event.coords.start.x;
|
|
scope.$event.directionY = scope.$event.coords.end.y - scope.$event.coords.start.y;
|
|
scope.$event.offsetX = Math.abs(scope.$event.directionX);
|
|
scope.$event.offsetY = Math.abs(scope.$event.directionY);
|
|
if (scope.$event.offsetX <= scope.$event.threshold && scope.$event.offsetY <= scope.$event.threshold) {
|
|
if (!!attrs["hold"] && scope.$event.time.duration >= scope.$event.holdfor) fn("hold"); else fn("secureTap");
|
|
} else if (scope.$event.offsetX >= scope.$event.offsetY) fn(scope.$event.directionX > 0 ? "swipeRight" : "swipeLeft"); else fn(scope.$event.directionY > 0 ? "swipeDown" : "swipeUp");
|
|
}
|
|
};
|
|
scope.$event.target.addEventListener(scope.$event.types.start, onStartEvent, false);
|
|
scope.$event.target.addEventListener(scope.$event.types.end, onEndEvent, false);
|
|
if (!!scope.$event.types.cancel) scope.$event.target.addEventListener(scope.$event.types.cancel, onEndEvent, false);
|
|
if (!!attrs["hold"]) scope.$event.target.addEventListener(scope.$event.types.move, onMoveEvent, false);
|
|
}
|
|
};
|
|
return {
|
|
restrict: "A",
|
|
link: touchEngine
|
|
};
|
|
} ]); |