aboutsummaryrefslogtreecommitdiffstats
path: root/src/ngTouch/directive/ngSwipe.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/ngTouch/directive/ngSwipe.js')
-rw-r--r--src/ngTouch/directive/ngSwipe.js114
1 files changed, 114 insertions, 0 deletions
diff --git a/src/ngTouch/directive/ngSwipe.js b/src/ngTouch/directive/ngSwipe.js
new file mode 100644
index 00000000..e754113c
--- /dev/null
+++ b/src/ngTouch/directive/ngSwipe.js
@@ -0,0 +1,114 @@
+'use strict';
+
+/**
+ * @ngdoc directive
+ * @name ngTouch.directive:ngSwipeLeft
+ *
+ * @description
+ * Specify custom behavior when an element is swiped to the left on a touchscreen device.
+ * A leftward swipe is a quick, right-to-left slide of the finger.
+ * Though ngSwipeLeft is designed for touch-based devices, it will work with a mouse click and drag too.
+ *
+ * @element ANY
+ * @param {expression} ngSwipeLeft {@link guide/expression Expression} to evaluate
+ * upon left swipe. (Event object is available as `$event`)
+ *
+ * @example
+ <doc:example>
+ <doc:source>
+ <div ng-show="!showActions" ng-swipe-left="showActions = true">
+ Some list content, like an email in the inbox
+ </div>
+ <div ng-show="showActions" ng-swipe-right="showActions = false">
+ <button ng-click="reply()">Reply</button>
+ <button ng-click="delete()">Delete</button>
+ </div>
+ </doc:source>
+ </doc:example>
+ */
+
+/**
+ * @ngdoc directive
+ * @name ngTouch.directive:ngSwipeRight
+ *
+ * @description
+ * Specify custom behavior when an element is swiped to the right on a touchscreen device.
+ * A rightward swipe is a quick, left-to-right slide of the finger.
+ * Though ngSwipeRight is designed for touch-based devices, it will work with a mouse click and drag too.
+ *
+ * @element ANY
+ * @param {expression} ngSwipeRight {@link guide/expression Expression} to evaluate
+ * upon right swipe. (Event object is available as `$event`)
+ *
+ * @example
+ <doc:example>
+ <doc:source>
+ <div ng-show="!showActions" ng-swipe-left="showActions = true">
+ Some list content, like an email in the inbox
+ </div>
+ <div ng-show="showActions" ng-swipe-right="showActions = false">
+ <button ng-click="reply()">Reply</button>
+ <button ng-click="delete()">Delete</button>
+ </div>
+ </doc:source>
+ </doc:example>
+ */
+
+function makeSwipeDirective(directiveName, direction, eventName) {
+ ngTouch.directive(directiveName, ['$parse', '$swipe', function($parse, $swipe) {
+ // The maximum vertical delta for a swipe should be less than 75px.
+ var MAX_VERTICAL_DISTANCE = 75;
+ // Vertical distance should not be more than a fraction of the horizontal distance.
+ var MAX_VERTICAL_RATIO = 0.3;
+ // At least a 30px lateral motion is necessary for a swipe.
+ var MIN_HORIZONTAL_DISTANCE = 30;
+
+ return function(scope, element, attr) {
+ var swipeHandler = $parse(attr[directiveName]);
+
+ var startCoords, valid;
+
+ function validSwipe(coords) {
+ // Check that it's within the coordinates.
+ // Absolute vertical distance must be within tolerances.
+ // Horizontal distance, we take the current X - the starting X.
+ // This is negative for leftward swipes and positive for rightward swipes.
+ // After multiplying by the direction (-1 for left, +1 for right), legal swipes
+ // (ie. same direction as the directive wants) will have a positive delta and
+ // illegal ones a negative delta.
+ // Therefore this delta must be positive, and larger than the minimum.
+ if (!startCoords) return false;
+ var deltaY = Math.abs(coords.y - startCoords.y);
+ var deltaX = (coords.x - startCoords.x) * direction;
+ return valid && // Short circuit for already-invalidated swipes.
+ deltaY < MAX_VERTICAL_DISTANCE &&
+ deltaX > 0 &&
+ deltaX > MIN_HORIZONTAL_DISTANCE &&
+ deltaY / deltaX < MAX_VERTICAL_RATIO;
+ }
+
+ $swipe.bind(element, {
+ 'start': function(coords) {
+ startCoords = coords;
+ valid = true;
+ },
+ 'cancel': function() {
+ valid = false;
+ },
+ 'end': function(coords) {
+ if (validSwipe(coords)) {
+ scope.$apply(function() {
+ element.triggerHandler(eventName);
+ swipeHandler(scope);
+ });
+ }
+ }
+ });
+ };
+ }]);
+}
+
+// Left is negative X-coordinate, right is positive.
+makeSwipeDirective('ngSwipeLeft', -1, 'swipeleft');
+makeSwipeDirective('ngSwipeRight', 1, 'swiperight');
+