diff options
Diffstat (limited to 'src/ngTouch/directive/ngSwipe.js')
| -rw-r--r-- | src/ngTouch/directive/ngSwipe.js | 114 | 
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'); + | 
