1
1
/*
2
- * angular-scrolly - v0.0.2 - 2013-07-30
2
+ * angular-scrolly - v0.0.3 - 2013-08-09
3
3
* http://github.com/ajoslin/angular-scrolly
4
4
* Created by Andy Joslin; Licensed under Public Domain
5
5
*/
6
6
angular . module ( 'ajoslin.scrolly' , [
7
- 'ajoslin.scrolly.dragger' ,
8
- 'ajoslin.scrolly.transformer' ,
9
7
'ajoslin.scrolly.scroller' ,
10
8
'ajoslin.scrolly.directives'
11
9
] ) ; angular . module ( 'ajoslin.scrolly.directives' , [ 'ajoslin.scrolly.scroller' ] ) . directive ( 'scrollyScroll' , [
@@ -22,56 +20,78 @@ angular.module('ajoslin.scrolly', [
22
20
}
23
21
} ;
24
22
}
25
- ] ) ; angular . module ( 'ajoslin.scrolly.desktop' , [ ] ) . factory ( '$desktopScroller' , [
26
- '$document' ,
27
- function ( $document ) {
28
- return function $desktopScroller ( elm , scroller ) {
29
- elm . bind ( '$destroy' , function ( ) {
30
- $document . unbind ( 'mousewheel' , onMousewheel ) ;
31
- $document . unbind ( 'keydown' , onKey ) ;
32
- } ) ;
33
- $document . bind ( 'mousewheel' , onMousewheel ) ;
34
- $document . bind ( 'keydown' , onKey ) ;
35
- function onMousewheel ( e ) {
36
- var delta = e . wheelDeltaY / 2 ;
37
- scroller . calculateHeight ( ) ;
38
- var newPos = scroller . transformer . pos + delta ;
39
- scroller . transformer . setTo ( clamp ( - scroller . scrollHeight , newPos , 0 ) ) ;
40
- e . preventDefault ( ) ;
41
- }
42
- var KEYS = {
43
- 38 : 150 ,
44
- 40 : - 150 ,
45
- 32 : - 600
46
- } ;
47
- function onKey ( e ) {
48
- var delta = KEYS [ e . keyCode || e . which ] ;
49
- if ( delta ) {
50
- e . preventDefault ( ) ;
51
- if ( scroller . transformer . changing )
52
- return ;
23
+ ] ) ; angular . module ( 'ajoslin.scrolly.desktop' , [ ] ) . provider ( '$desktopScroller' , function ( ) {
24
+ var KEYS = {
25
+ 38 : 150 ,
26
+ 40 : - 150 ,
27
+ 32 : - 600
28
+ } ;
29
+ this . key = function ( keyCode , delta ) {
30
+ if ( arguments . length > 1 ) {
31
+ KEYS [ keyCode ] = delta ;
32
+ }
33
+ return KEYS [ keyCode ] ;
34
+ } ;
35
+ var _mouseWheelDistanceMulti = 0.5 ;
36
+ this . mouseWheelDistanceMulti = function ( newMulti ) {
37
+ arguments . length && ( _mouseWheelDistanceMulti = newMulti ) ;
38
+ return _mouseWheelDistanceMulti ;
39
+ } ;
40
+ this . $get = [
41
+ '$document' ,
42
+ function ( $document ) {
43
+ $desktopScroller . mouseWheelDistanceMulti = _mouseWheelDistanceMulti ;
44
+ $desktopScroller . easeTimeMulti = 0.66 ;
45
+ function $desktopScroller ( elm , scroller ) {
46
+ var self = { } ;
47
+ elm . bind ( '$destroy' , function ( ) {
48
+ $document . unbind ( 'mousewheel' , onMousewheel ) ;
49
+ $document . unbind ( 'keydown' , onKey ) ;
50
+ } ) ;
51
+ $document . bind ( 'mousewheel' , onMousewheel ) ;
52
+ $document . bind ( 'keydown' , onKey ) ;
53
+ function onMousewheel ( e ) {
54
+ var delta = e . wheelDeltaY * $desktopScroller . mouseWheelDistanceMulti ;
53
55
scroller . calculateHeight ( ) ;
54
56
var newPos = scroller . transformer . pos + delta ;
55
- newPos = clamp ( - scroller . scrollHeight , newPos , 0 ) ;
56
- if ( newPos !== scroller . transformer . pos ) {
57
- var newDelta = newPos - scroller . transformer . pos ;
58
- var time = Math . abs ( delta / 1.5 ) * ( newDelta / delta ) ;
59
- scroller . transformer . easeTo ( newPos , time ) ;
57
+ scroller . transformer . setTo ( clamp ( - scroller . scrollHeight , newPos , 0 ) ) ;
58
+ e . preventDefault ( ) ;
59
+ }
60
+ var INPUT_REGEX = / I N P U T | T E X T A R E A | S E L E C T / i;
61
+ function onKey ( e ) {
62
+ if ( document . activeElement && document . activeElement . tagName && document . activeElement . tagName . match ( INPUT_REGEX ) ) {
63
+ return ;
64
+ }
65
+ var delta = KEYS [ e . keyCode || e . which ] ;
66
+ if ( delta ) {
67
+ e . preventDefault ( ) ;
68
+ if ( scroller . transformer . changing )
69
+ return ;
70
+ scroller . calculateHeight ( ) ;
71
+ var newPos = scroller . transformer . pos + delta ;
72
+ newPos = clamp ( - scroller . scrollHeight , newPos , 0 ) ;
73
+ if ( newPos !== scroller . transformer . pos ) {
74
+ var newDelta = newPos - scroller . transformer . pos ;
75
+ var time = Math . abs ( newDelta * $desktopScroller . easeTimeMulti ) ;
76
+ scroller . transformer . easeTo ( newPos , time ) ;
77
+ }
60
78
}
61
79
}
80
+ return self ;
62
81
}
63
- } ;
64
- function clamp ( a , b , c ) {
65
- return Math . min ( Math . max ( a , b ) , c ) ;
82
+ function clamp ( a , b , c ) {
83
+ return Math . min ( Math . max ( a , b ) , c ) ;
84
+ }
85
+ return $desktopScroller ;
66
86
}
67
- }
68
- ] ) ; angular . module ( 'ajoslin.scrolly.dragger' , [ ] ) . provider ( '$dragger' , function ( ) {
87
+ ] ;
88
+ } ) ; angular . module ( 'ajoslin.scrolly.dragger' , [ ] ) . provider ( '$dragger' , function ( ) {
69
89
var _shouldBlurOnDrag = true ;
70
90
this . shouldBlurOnDrag = function ( shouldBlur ) {
71
91
arguments . length && ( _shouldBlurOnDrag = ! ! shouldBlur ) ;
72
92
return _shouldBlurOnDrag ;
73
93
} ;
74
- var _minDistanceForDrag = 6 ;
94
+ var _minDistanceForDrag = 8 ;
75
95
this . minDistanceForDrag = function ( newMinDistanceForDrag ) {
76
96
arguments . length && ( _minDistanceForDrag = newMinDistanceForDrag ) ;
77
97
return _minDistanceForDrag ;
@@ -94,9 +114,24 @@ angular.module('ajoslin.scrolly', [
94
114
'$window' ,
95
115
'$document' ,
96
116
function ( $window , $document ) {
97
- function $dragger ( elm ) {
117
+ function getX ( point ) {
118
+ return point . pageX ;
119
+ }
120
+ function getY ( point ) {
121
+ return point . pageY ;
122
+ }
123
+ function $dragger ( elm , options ) {
98
124
var self = { } ;
99
125
var raw = elm [ 0 ] ;
126
+ var getPos , getOtherPos ;
127
+ options = options || { } ;
128
+ if ( options . horizontal ) {
129
+ getPos = getX ;
130
+ getOtherPos = getY ;
131
+ } else {
132
+ getPos = getY ;
133
+ getOtherPos = getX ;
134
+ }
100
135
var state = {
101
136
startPos : 0 ,
102
137
startTime : 0 ,
@@ -116,19 +151,20 @@ angular.module('ajoslin.scrolly', [
116
151
elm . bind ( 'touchstart' , dragStart ) ;
117
152
elm . bind ( 'touchmove' , dragMove ) ;
118
153
elm . bind ( 'touchend touchcancel' , dragEnd ) ;
119
- function restartDragState ( y ) {
120
- state . startPos = state . pos = y ;
154
+ function restartDragState ( point ) {
155
+ state . startPos = state . pos = getPos ( point ) ;
156
+ state . otherStartPos = state . otherPos = getOtherPos ( point ) ;
121
157
state . startTime = Date . now ( ) ;
122
158
state . dragging = true ;
123
159
}
124
160
function isInput ( raw ) {
125
- return raw && raw . tagName === 'INPUT' || raw . tagName === 'SELECT' || raw . tagName === 'TEXTAREA' ;
161
+ return raw && ( raw . tagName === 'INPUT' || raw . tagName === 'SELECT' || raw . tagName === 'TEXTAREA' ) ;
126
162
}
127
163
function dragStart ( e ) {
128
164
e = e . originalEvent || e ;
129
165
var target = e . target || e . srcElement ;
130
166
var point = e . touches ? e . touches [ 0 ] : e ;
131
- if ( parentWithAttr ( target , 'data- dragger-ignore' ) ) {
167
+ if ( parentWithAttr ( target , 'dragger-ignore' ) ) {
132
168
return ;
133
169
}
134
170
if ( _shouldBlurOnDrag && isInput ( target ) ) {
@@ -139,7 +175,7 @@ angular.module('ajoslin.scrolly', [
139
175
state . delta = 0 ;
140
176
state . pos = 0 ;
141
177
state . distance = 0 ;
142
- restartDragState ( point . pageY ) ;
178
+ restartDragState ( point ) ;
143
179
dispatchEvent ( {
144
180
type : 'start' ,
145
181
startPos : state . startPos ,
@@ -151,17 +187,24 @@ angular.module('ajoslin.scrolly', [
151
187
e . preventDefault ( ) ;
152
188
if ( state . dragging ) {
153
189
var point = e . touches ? e . touches [ 0 ] : e ;
154
- var delta = point . pageY - state . pos ;
190
+ var delta = getPos ( point ) - state . pos ;
155
191
state . delta = delta ;
156
- state . pos = point . pageY ;
192
+ state . pos = getPos ( point ) ;
193
+ state . otherPos = getOtherPos ( point ) ;
157
194
state . distance = state . pos - state . startPos ;
158
- if ( Math . abs ( state . pos - state . startPos ) < _minDistanceForDrag ) {
159
- return ;
195
+ state . otherDistance = state . otherPos - state . otherStartPos ;
196
+ if ( ! state . moved ) {
197
+ if ( Math . abs ( state . otherDistance ) > _minDistanceForDrag ) {
198
+ return dragEnd ( e ) ;
199
+ } else if ( Math . abs ( state . distance ) > _minDistanceForDrag ) {
200
+ state . moved = true ;
201
+ } else {
202
+ return ;
203
+ }
160
204
}
161
- state . moved = true ;
162
205
var timeSinceMove = state . lastMoveTime - state . startTime ;
163
206
if ( timeSinceMove > _maxTimeMotionless ) {
164
- restartDragState ( state . pos ) ;
207
+ restartDragState ( point ) ;
165
208
}
166
209
state . lastMoveTime = e . timeStamp || Date . now ( ) ;
167
210
dispatchEvent ( {
@@ -276,6 +319,12 @@ angular.module('ajoslin.scrolly', [
276
319
}
277
320
function $scroller ( elm ) {
278
321
var self = { } ;
322
+ var currentScroller = elm . data ( '$scrolly.scroller' ) ;
323
+ if ( currentScroller ) {
324
+ return currentScroller ;
325
+ } else {
326
+ elm . data ( '$scrolly.scroller' , self ) ;
327
+ }
279
328
var raw = elm [ 0 ] ;
280
329
var transformer = self . transformer = new $transformer ( elm ) ;
281
330
var dragger = self . dragger = new $dragger ( elm ) ;
@@ -407,11 +456,17 @@ angular.module('ajoslin.scrolly', [
407
456
}
408
457
function $transformer ( elm , options ) {
409
458
var self = { } ;
459
+ var currentTransformer = elm . data ( '$scrolly.transformer' ) ;
460
+ if ( currentTransformer ) {
461
+ return currentTransformer ;
462
+ } else {
463
+ elm . data ( '$scrolly.transformer' , self ) ;
464
+ }
410
465
var raw = elm [ 0 ] ;
411
466
var _transformGetter ;
412
467
var _matrixIndex ;
413
468
options = options || { } ;
414
- if ( options . translateX ) {
469
+ if ( options . horizontal ) {
415
470
_transformGetter = transformGetterX ;
416
471
_matrixIndex = 4 ;
417
472
} else {
0 commit comments