├── .bowerrc
├── .editorconfig
├── .gitattributes
├── .gitignore
├── .jshintrc
├── Gruntfile.js
├── LICENSE.txt
├── README.md
├── bower.json
├── dist
├── angular-swipe.js
└── angular-swipe.min.js
├── package.json
└── src
├── angular-swipe.js
├── app.js
└── index.html
/.bowerrc:
--------------------------------------------------------------------------------
1 | {
2 | "directory": "bower_components"
3 | }
4 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent
2 | # coding styles between different editors and IDEs
3 | # editorconfig.org
4 |
5 | root = true
6 |
7 |
8 | [*]
9 |
10 | # Change these settings to your own preference
11 | indent_style = space
12 | indent_size = 2
13 |
14 | # We recommend you to keep these unchanged
15 | end_of_line = lf
16 | charset = utf-8
17 | trim_trailing_whitespace = true
18 | insert_final_newline = true
19 |
20 | [*.md]
21 | trim_trailing_whitespace = false
22 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .tmp
3 | bower_components
4 | test
5 |
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "node": true,
3 | "browser": true,
4 | "sub": true,
5 | "esnext": true,
6 | "bitwise": true,
7 | "camelcase": true,
8 | "curly": true,
9 | "expr": true,
10 | "eqeqeq": true,
11 | "immed": true,
12 | "indent": 2,
13 | "latedef": true,
14 | "newcap": true,
15 | "noarg": true,
16 | "quotmark": "single",
17 | "regexp": true,
18 | "undef": true,
19 | "unused": true,
20 | "strict": true,
21 | "trailing": true,
22 | "smarttabs": true,
23 | "jquery": true,
24 | "globals": {
25 | "angular": false
26 | },
27 | "predef": [ "angular" ]
28 | }
29 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function (grunt) {
4 | // load all grunt tasks
5 | require('load-grunt-tasks')(grunt);
6 |
7 | grunt.initConfig({
8 | // configurable paths
9 | yeoman: {
10 | app: 'src',
11 | dist: 'dist'
12 | },
13 |
14 | watch: {
15 | livereload: {
16 | options: {
17 | livereload: '<%= connect.options.livereload %>'
18 | },
19 | files: [
20 | '<%= yeoman.app %>/*.html',
21 | '{.tmp,<%= yeoman.app %>}/scripts/{,*/}*.js'
22 | ]
23 | }
24 | },
25 |
26 | connect: {
27 | options: {
28 | port: 9000,
29 | livereload: 35729,
30 | hostname: 'localhost'
31 | },
32 | livereload: {
33 | options: {
34 | open: true,
35 | base: [
36 | '.tmp',
37 | 'bower_components',
38 | '<%= yeoman.app %>'
39 | ]
40 | }
41 | },
42 | test: {
43 | options: {
44 | base: [
45 | '.tmp',
46 | 'test',
47 | '<%= yeoman.app %>'
48 | ]
49 | }
50 | },
51 | dist: {
52 | options: {
53 | open: true,
54 | base: '<%= yeoman.dist %>',
55 | livereload: false
56 | }
57 | }
58 | },
59 |
60 | clean: {
61 | dist: {
62 | files: [{
63 | dot: true,
64 | src: [
65 | '.tmp',
66 | '<%= yeoman.dist %>/*',
67 | '!<%= yeoman.dist %>/.git*'
68 | ]
69 | }]
70 | },
71 | server: '.tmp'
72 | },
73 |
74 | jshint: {
75 | options: {
76 | jshintrc: '.jshintrc'
77 | },
78 | all: [
79 | '<%= yeoman.app %>/{,*/}*.js'
80 | ]
81 | },
82 |
83 | copy: {
84 | dist: {
85 | files: [{
86 | expand: true,
87 | dot: true,
88 | cwd: '<%= yeoman.app %>',
89 | dest: '<%= yeoman.dist %>',
90 | src: [
91 | 'angular-swipe.js'
92 | ]
93 | }]
94 | }
95 | },
96 |
97 | concat: {
98 | options: {
99 | separator: ';'
100 | },
101 | dist: {
102 | src: ['<%= yeoman.app %>/angular-swipe.js'],
103 | dest: '<%= yeoman.dist %>/angular-swipe.min.js'
104 | }
105 | },
106 |
107 | uglify: {
108 | options: {
109 | banner: '/*! angular-swipe.min.js <%= grunt.template.today("dd-mm-yyyy") %> */\n'
110 | },
111 | dist: {
112 | files: {
113 | 'dist/angular-swipe.min.js': ['<%= concat.dist.dest %>']
114 | }
115 | }
116 | }
117 |
118 | });
119 |
120 | grunt.registerTask('serve', function (target) {
121 | if (target === 'dist') {
122 | return grunt.task.run(['build', 'connect:dist:keepalive']);
123 | }
124 |
125 | grunt.task.run([
126 | 'clean:server',
127 | 'connect:livereload',
128 | 'watch'
129 | ]);
130 | });
131 |
132 | grunt.registerTask('build', [
133 | 'clean:dist',
134 | 'concat',
135 | 'uglify',
136 | 'copy:dist'
137 | ]);
138 |
139 | grunt.registerTask('default', [
140 | 'jshint',
141 | 'build'
142 | ]);
143 | };
144 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | The MIT License
2 |
3 | Copyright (c) 2010-2017 Google, Inc. http://angularjs.org
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | angular-swipe
2 | =============
3 |
4 | Simple vertical/horizontal swipe gesture directives and a swipe service for angular js >= 1.6. Small extension of the existing angular $swipe service.
5 |
6 | ## Install
7 |
8 | + Add this line to your *bower.json* dependencies and run *bower install* afterwards.
9 |
10 | >
11 | ``` JavaScript
12 | "angular-swipe": "~0.2.1"
13 | ```
14 |
15 | + Include the required source file (this path or similar)
16 |
17 | >
18 | ``` html
19 |
20 | ```
21 |
22 | + Inject the `swipe` module into your app.
23 |
24 | >
25 | ``` JavaScript
26 | angular.module('app', ['swipe']);
27 | ```
28 |
29 | ## Usage
30 |
31 | #### Module Name (Dependency)
32 |
33 | * swipe
34 |
35 | #### Directives
36 |
37 | * ng-swipe-up
38 | * ng-swipe-down
39 | * ng-swipe-left
40 | * ng-swipe-right
41 |
42 | #### Directive Attributes
43 |
44 | `ng-swipe-disable-mouse` "This attribute is useful for text that should still be selectable by the mouse and not trigger the swipe action."
45 |
46 | #### Service
47 |
48 | * swipe
49 |
50 | ## Example
51 |
52 | >
53 | ```html
54 |
55 |
56 |
Swipe me up!
57 |
58 |
59 | ```
60 |
61 | >
62 | ```JavaScript
63 | var app = angular.module('app', [ 'swipe' ]);
64 | app.controller('AppCtrl', function AppCtrl($scope) {
65 | $scope.swipe = function($event) {
66 | console.log($event);
67 | };
68 | })
69 | ```
70 |
71 | ## Known issues and workarounds
72 |
73 | * ng-swipe-up and ng-swipe-down uses preventDefault when you start swiping. This prevents clicks from giving focus to input fields. Adding a `noPreventDefault` class to these elements will not preventDefault when the swipe start on them and thus allow clicks to work.
74 |
75 | * When embedding a Google map you might want to prevent a swipe event specifically inside the map. You can do that by adding the `noStartDrag` class to the Google map HTML element
76 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-swipe",
3 | "description": "Simple vertical and horizontal swipe gesture directive for angular js",
4 | "version": "0.2.1",
5 | "authors": [
6 | "marmorkuchen.net "
7 | ],
8 | "homepage": "https://github.com/adzialocha/angular-swipe",
9 | "repository": {
10 | "type": "git",
11 | "url": "git@github.com:adzialocha/angular-swipe.git"
12 | },
13 | "keywords": [
14 | "swipe",
15 | "horizontal",
16 | "touch",
17 | "vertical",
18 | "gesture",
19 | "mobile",
20 | "angularjs",
21 | "angular",
22 | "directive"
23 | ],
24 | "main": "./dist/angular-swipe.js",
25 | "dependencies": {
26 | "angular": "~1.6.x"
27 | },
28 | "ignore": [
29 | ".jshintrc",
30 | "Gruntfile.js",
31 | "package.json",
32 | "src"
33 | ],
34 | "devDependencies": {},
35 | "private": false,
36 | "license": "MIT"
37 | }
38 |
--------------------------------------------------------------------------------
/dist/angular-swipe.js:
--------------------------------------------------------------------------------
1 | (function(window, angular, undefined) {
2 | 'use strict';
3 |
4 | /* global -ngSwipe */
5 |
6 | var ngSwipe = angular.module('swipe', []);
7 |
8 | ngSwipe.factory('swipe', [ function() {
9 |
10 | var MOVE_BUFFER_RADIUS = 40;
11 | var MAX_RATIO = 0.3;
12 |
13 | var POINTER_EVENTS = {
14 | 'mouse': {
15 | start: 'mousedown',
16 | move: 'mousemove',
17 | end: 'mouseup'
18 | },
19 | 'touch': {
20 | start: 'touchstart',
21 | move: 'touchmove',
22 | end: 'touchend',
23 | cancel: 'touchcancel'
24 | }
25 | };
26 |
27 | function getCoordinates(event) {
28 | var originalEvent = event.originalEvent || event;
29 | var touches = originalEvent.touches && originalEvent.touches.length ? originalEvent.touches : [originalEvent];
30 | var e = (originalEvent.changedTouches && originalEvent.changedTouches[0]) || touches[0];
31 |
32 | return {
33 | x: e.clientX,
34 | y: e.clientY
35 | };
36 | }
37 |
38 | function getEvents(pointerTypes, eventType) {
39 | var res = [];
40 | angular.forEach(pointerTypes, function(pointerType) {
41 | var eventName = POINTER_EVENTS[pointerType][eventType];
42 | if (eventName) {
43 | res.push(eventName);
44 | }
45 | });
46 | return res.join(' ');
47 | }
48 |
49 | return {
50 |
51 | bind: function(element, eventHandlers, pointerTypes) {
52 |
53 | // Absolute total movement
54 | var totalX, totalY;
55 | // Coordinates of the start position.
56 | var startCoords;
57 | var lastPos;
58 | // Whether a swipe is active.
59 | var active = false;
60 | // Decide where we are going
61 | var isDecided = false;
62 | var isVertical = true;
63 |
64 | pointerTypes = pointerTypes || ['mouse', 'touch'];
65 |
66 | element.on(getEvents(pointerTypes, 'start'), function(event) {
67 | startCoords = getCoordinates(event);
68 | active = true;
69 | totalX = 0;
70 | totalY = 0;
71 | isDecided = false;
72 | isVertical = true;
73 | lastPos = startCoords;
74 | eventHandlers['start'] && eventHandlers['start'](startCoords, event);
75 | });
76 |
77 | element.on(getEvents(pointerTypes, 'cancel'), function(event) {
78 | active = false;
79 | eventHandlers['cancel'] && eventHandlers['cancel'](event);
80 | });
81 |
82 | element.on(getEvents(pointerTypes, 'move'), function(event) {
83 |
84 | if (! active) {
85 | return;
86 | }
87 |
88 | if (! startCoords) {
89 | return;
90 | }
91 |
92 | var coords = getCoordinates(event);
93 |
94 | totalX += Math.abs(coords.x - lastPos.x);
95 | totalY += Math.abs(coords.y - lastPos.y);
96 |
97 | lastPos = coords;
98 |
99 | if (totalX < MOVE_BUFFER_RADIUS && totalY < MOVE_BUFFER_RADIUS) {
100 | return;
101 | } else {
102 | if (! isDecided){
103 |
104 | var deltaX, deltaY, ratio;
105 |
106 | deltaX = Math.abs(coords.x - startCoords.x);
107 | deltaY = Math.abs(coords.y - startCoords.y);
108 |
109 | ratio = deltaY / deltaX;
110 |
111 | if (ratio < MAX_RATIO){
112 | event.preventDefault();
113 | isVertical = false;
114 | } else {
115 | isVertical = true;
116 | }
117 |
118 | isDecided = true;
119 | }
120 | }
121 |
122 | event.isVertical = isVertical;
123 | eventHandlers['move'] && eventHandlers['move'](coords, event);
124 | });
125 |
126 | element.on(getEvents(pointerTypes, 'end'), function(event) {
127 | if (! active){
128 | return;
129 | }
130 | event.isVertical = isVertical;
131 | active = false;
132 | eventHandlers['end'] && eventHandlers['end'](getCoordinates(event), event);
133 | });
134 | }
135 | };
136 | }]);
137 |
138 | function makeSwipeDirective(directiveName, direction, axis, eventName) {
139 | ngSwipe.directive(directiveName, ['$parse', 'swipe', function($parse, swipe) {
140 |
141 | var MAX_OTHER_AXIS_DISTANCE = 75;
142 | var MAX_RATIO = 0.3;
143 | var MIN_DISTANCE = 30;
144 |
145 | return function(scope, element, attr) {
146 |
147 | var swipeHandler = $parse(attr[directiveName]);
148 |
149 | var startCoords, valid;
150 |
151 | function checkOverride(element, clazz) {
152 | do {
153 | var className = element.getAttribute('class');
154 | if (className && className.match(clazz) !== null) {
155 | return true;
156 | }
157 | element = element.parentElement;
158 | } while (element !== null);
159 | return false;
160 | }
161 |
162 | function validSwipe(coords) {
163 |
164 | if (! startCoords || ! valid){
165 | return false;
166 | }
167 |
168 | var deltaY = (coords.y - startCoords.y) * direction;
169 | var deltaX = (coords.x - startCoords.x) * direction;
170 |
171 | if(axis === null) { // tap
172 | return Math.abs(deltaY) < MIN_DISTANCE &&
173 | Math.abs(deltaX) < MIN_DISTANCE;
174 | }
175 | else if(axis === false) { // horizontal swipe
176 | return Math.abs(deltaY) < MAX_OTHER_AXIS_DISTANCE &&
177 | deltaX > 0 &&
178 | deltaX > MIN_DISTANCE &&
179 | Math.abs(deltaY) / deltaX < MAX_RATIO;
180 | }
181 | else { // vertical swipe
182 | return Math.abs(deltaX) < MAX_OTHER_AXIS_DISTANCE &&
183 | deltaY > 0 &&
184 | deltaY > MIN_DISTANCE &&
185 | Math.abs(deltaX) / deltaY < MAX_RATIO;
186 | }
187 | }
188 |
189 | var pointerTypes = ['touch'];
190 |
191 | if (!angular.isDefined(attr['ngSwipeDisableMouse'])) {
192 | pointerTypes.push('mouse');
193 | }
194 |
195 | swipe.bind(element, {
196 | 'start': function(coords, event) {
197 | if (axis && !checkOverride(event.target, 'noPreventDefault')) {
198 | event.preventDefault();
199 | }
200 | startCoords = coords;
201 | valid = !checkOverride(event.target, 'noStartDrag');
202 | },
203 | 'cancel': function() {
204 | valid = false;
205 | },
206 | 'end': function(coords, event) {
207 | if (validSwipe(coords)) {
208 | scope.$apply(function() {
209 | element.triggerHandler(eventName);
210 | swipeHandler(scope, { $event: event });
211 | });
212 | }
213 | }
214 | }, pointerTypes);
215 | };
216 | }]);
217 | }
218 |
219 | // avoid conflicts with ngTouch module
220 |
221 | try {
222 | angular.module('ngTouch');
223 | } catch(err) {
224 | makeSwipeDirective('ngSwipeLeft', -1, false, 'swipeleft');
225 | makeSwipeDirective('ngSwipeRight', 1, false, 'swiperight');
226 | }
227 |
228 | // left is negative x-coordinate, right is positive
229 |
230 | makeSwipeDirective('ngSwipeUp', -1, true, 'swipeup');
231 | makeSwipeDirective('ngSwipeDown', 1, true, 'swipedown');
232 |
233 | makeSwipeDirective('ngTap', 1, null, 'tap');
234 | })(window, window.angular);
235 |
--------------------------------------------------------------------------------
/dist/angular-swipe.min.js:
--------------------------------------------------------------------------------
1 | /*! angular-swipe.min.js 13-03-2017 */
2 | !function(a,b,c){"use strict";function d(a,c,d,f){e.directive(a,["$parse","swipe",function(e,g){var h=75,i=.3,j=30;return function(k,l,m){function n(a,b){do{var c=a.getAttribute("class");if(c&&null!==c.match(b))return!0;a=a.parentElement}while(null!==a);return!1}function o(a){if(!p||!q)return!1;var b=(a.y-p.y)*c,e=(a.x-p.x)*c;return null===d?Math.abs(b)0&&e>j&&Math.abs(b)/e0&&b>j&&Math.abs(e)/b=0.8.0"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/angular-swipe.js:
--------------------------------------------------------------------------------
1 | (function(window, angular, undefined) {
2 | 'use strict';
3 |
4 | /* global -ngSwipe */
5 |
6 | var ngSwipe = angular.module('swipe', []);
7 |
8 | ngSwipe.factory('swipe', [ function() {
9 |
10 | var MOVE_BUFFER_RADIUS = 40;
11 | var MAX_RATIO = 0.3;
12 |
13 | var POINTER_EVENTS = {
14 | 'mouse': {
15 | start: 'mousedown',
16 | move: 'mousemove',
17 | end: 'mouseup'
18 | },
19 | 'touch': {
20 | start: 'touchstart',
21 | move: 'touchmove',
22 | end: 'touchend',
23 | cancel: 'touchcancel'
24 | }
25 | };
26 |
27 | function getCoordinates(event) {
28 | var originalEvent = event.originalEvent || event;
29 | var touches = originalEvent.touches && originalEvent.touches.length ? originalEvent.touches : [originalEvent];
30 | var e = (originalEvent.changedTouches && originalEvent.changedTouches[0]) || touches[0];
31 |
32 | return {
33 | x: e.clientX,
34 | y: e.clientY
35 | };
36 | }
37 |
38 | function getEvents(pointerTypes, eventType) {
39 | var res = [];
40 | angular.forEach(pointerTypes, function(pointerType) {
41 | var eventName = POINTER_EVENTS[pointerType][eventType];
42 | if (eventName) {
43 | res.push(eventName);
44 | }
45 | });
46 | return res.join(' ');
47 | }
48 |
49 | return {
50 |
51 | bind: function(element, eventHandlers, pointerTypes) {
52 |
53 | // Absolute total movement
54 | var totalX, totalY;
55 | // Coordinates of the start position.
56 | var startCoords;
57 | var lastPos;
58 | // Whether a swipe is active.
59 | var active = false;
60 | // Decide where we are going
61 | var isDecided = false;
62 | var isVertical = true;
63 |
64 | pointerTypes = pointerTypes || ['mouse', 'touch'];
65 |
66 | element.on(getEvents(pointerTypes, 'start'), function(event) {
67 | startCoords = getCoordinates(event);
68 | active = true;
69 | totalX = 0;
70 | totalY = 0;
71 | isDecided = false;
72 | isVertical = true;
73 | lastPos = startCoords;
74 | eventHandlers['start'] && eventHandlers['start'](startCoords, event);
75 | });
76 |
77 | element.on(getEvents(pointerTypes, 'cancel'), function(event) {
78 | active = false;
79 | eventHandlers['cancel'] && eventHandlers['cancel'](event);
80 | });
81 |
82 | element.on(getEvents(pointerTypes, 'move'), function(event) {
83 |
84 | if (! active) {
85 | return;
86 | }
87 |
88 | if (! startCoords) {
89 | return;
90 | }
91 |
92 | var coords = getCoordinates(event);
93 |
94 | totalX += Math.abs(coords.x - lastPos.x);
95 | totalY += Math.abs(coords.y - lastPos.y);
96 |
97 | lastPos = coords;
98 |
99 | if (totalX < MOVE_BUFFER_RADIUS && totalY < MOVE_BUFFER_RADIUS) {
100 | return;
101 | } else {
102 | if (! isDecided){
103 |
104 | var deltaX, deltaY, ratio;
105 |
106 | deltaX = Math.abs(coords.x - startCoords.x);
107 | deltaY = Math.abs(coords.y - startCoords.y);
108 |
109 | ratio = deltaY / deltaX;
110 |
111 | if (ratio < MAX_RATIO){
112 | event.preventDefault();
113 | isVertical = false;
114 | } else {
115 | isVertical = true;
116 | }
117 |
118 | isDecided = true;
119 | }
120 | }
121 |
122 | event.isVertical = isVertical;
123 | eventHandlers['move'] && eventHandlers['move'](coords, event);
124 | });
125 |
126 | element.on(getEvents(pointerTypes, 'end'), function(event) {
127 | if (! active){
128 | return;
129 | }
130 | event.isVertical = isVertical;
131 | active = false;
132 | eventHandlers['end'] && eventHandlers['end'](getCoordinates(event), event);
133 | });
134 | }
135 | };
136 | }]);
137 |
138 | function makeSwipeDirective(directiveName, direction, axis, eventName) {
139 | ngSwipe.directive(directiveName, ['$parse', 'swipe', function($parse, swipe) {
140 |
141 | var MAX_OTHER_AXIS_DISTANCE = 75;
142 | var MAX_RATIO = 0.3;
143 | var MIN_DISTANCE = 30;
144 |
145 | return function(scope, element, attr) {
146 |
147 | var swipeHandler = $parse(attr[directiveName]);
148 |
149 | var startCoords, valid;
150 |
151 | function checkOverride(element, clazz) {
152 | do {
153 | var className = element.getAttribute('class');
154 | if (className && className.match(clazz) !== null) {
155 | return true;
156 | }
157 | element = element.parentElement;
158 | } while (element !== null);
159 | return false;
160 | }
161 |
162 | function validSwipe(coords) {
163 |
164 | if (! startCoords || ! valid){
165 | return false;
166 | }
167 |
168 | var deltaY = (coords.y - startCoords.y) * direction;
169 | var deltaX = (coords.x - startCoords.x) * direction;
170 |
171 | if(axis === null) { // tap
172 | return Math.abs(deltaY) < MIN_DISTANCE &&
173 | Math.abs(deltaX) < MIN_DISTANCE;
174 | }
175 | else if(axis === false) { // horizontal swipe
176 | return Math.abs(deltaY) < MAX_OTHER_AXIS_DISTANCE &&
177 | deltaX > 0 &&
178 | deltaX > MIN_DISTANCE &&
179 | Math.abs(deltaY) / deltaX < MAX_RATIO;
180 | }
181 | else { // vertical swipe
182 | return Math.abs(deltaX) < MAX_OTHER_AXIS_DISTANCE &&
183 | deltaY > 0 &&
184 | deltaY > MIN_DISTANCE &&
185 | Math.abs(deltaX) / deltaY < MAX_RATIO;
186 | }
187 | }
188 |
189 | var pointerTypes = ['touch'];
190 |
191 | if (!angular.isDefined(attr['ngSwipeDisableMouse'])) {
192 | pointerTypes.push('mouse');
193 | }
194 |
195 | swipe.bind(element, {
196 | 'start': function(coords, event) {
197 | if (axis && !checkOverride(event.target, 'noPreventDefault')) {
198 | event.preventDefault();
199 | }
200 | startCoords = coords;
201 | valid = !checkOverride(event.target, 'noStartDrag');
202 | },
203 | 'cancel': function() {
204 | valid = false;
205 | },
206 | 'end': function(coords, event) {
207 | if (validSwipe(coords)) {
208 | scope.$apply(function() {
209 | element.triggerHandler(eventName);
210 | swipeHandler(scope, { $event: event });
211 | });
212 | }
213 | }
214 | }, pointerTypes);
215 | };
216 | }]);
217 | }
218 |
219 | // avoid conflicts with ngTouch module
220 |
221 | try {
222 | angular.module('ngTouch');
223 | } catch(err) {
224 | makeSwipeDirective('ngSwipeLeft', -1, false, 'swipeleft');
225 | makeSwipeDirective('ngSwipeRight', 1, false, 'swiperight');
226 | }
227 |
228 | // left is negative x-coordinate, right is positive
229 |
230 | makeSwipeDirective('ngSwipeUp', -1, true, 'swipeup');
231 | makeSwipeDirective('ngSwipeDown', 1, true, 'swipedown');
232 |
233 | makeSwipeDirective('ngTap', 1, null, 'tap');
234 | })(window, window.angular);
235 |
--------------------------------------------------------------------------------
/src/app.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var app = angular.module('app', [ 'swipe' ]);
4 |
5 | app.controller('AppCtrl', function AppCtrl($scope) {
6 | $scope.message = 'Hey!';
7 | $scope.inputtest = '';
8 |
9 | $scope.swipe = function($event) {
10 | console.log($event);
11 | };
12 |
13 | $scope.$watch('inputtest', function(newVal) {
14 | $scope.message = 'Hey ' + newVal + '!';
15 | });
16 | });
17 |
--------------------------------------------------------------------------------
/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | angular swipe
9 |
10 |
11 |
12 |
13 |
14 |
15 |
27 |
28 |
29 |
30 |
31 |
32 |
Test Horizontal
33 |
34 |
{{ message }}
35 |
36 |
37 |
Test Vertical
38 |
39 |
{{ message }}
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------