11
11
12
12
angular . module ( 'rzModule' , [ ] )
13
13
14
- . factory ( 'Slider' , [ '$timeout' , '$document' , function ( $timeout , $document )
14
+ . value ( 'throttle' ,
15
+ // Taken from underscore project
16
+ function throttle ( func , wait , options ) {
17
+ var getTime = ( Date . now || function ( ) {
18
+ return new Date ( ) . getTime ( ) ;
19
+ } ) ;
20
+ var context , args , result ;
21
+ var timeout = null ;
22
+ var previous = 0 ;
23
+ options || ( options = { } ) ;
24
+ var later = function ( ) {
25
+ previous = options . leading === false ? 0 : getTime ( ) ;
26
+ timeout = null ;
27
+ result = func . apply ( context , args ) ;
28
+ context = args = null ;
29
+ } ;
30
+ return function ( ) {
31
+ var now = getTime ( ) ;
32
+ if ( ! previous && options . leading === false ) previous = now ;
33
+ var remaining = wait - ( now - previous ) ;
34
+ context = this ;
35
+ args = arguments ;
36
+ if ( remaining <= 0 ) {
37
+ clearTimeout ( timeout ) ;
38
+ timeout = null ;
39
+ previous = now ;
40
+ result = func . apply ( context , args ) ;
41
+ context = args = null ;
42
+ } else if ( ! timeout && options . trailing !== false ) {
43
+ timeout = setTimeout ( later , remaining ) ;
44
+ }
45
+ return result ;
46
+ }
47
+ } )
48
+
49
+ . factory ( 'Slider' , [ '$timeout' , '$document' , 'throttle' , function ( $timeout , $document , throttle )
15
50
{
16
51
/**
17
52
* Slider
@@ -107,6 +142,20 @@ angular.module('rzModule', [])
107
142
*/
108
143
this . maxValue = 0 ;
109
144
145
+ /**
146
+ * High value handle offset in percentages
147
+ *
148
+ * @type {number }
149
+ */
150
+ this . highValOffsetPerc = 0 ;
151
+
152
+ /**
153
+ * Low value handle offset in percentages
154
+ *
155
+ * @type {number }
156
+ */
157
+ this . lowValOffsetPerc = 0 ;
158
+
110
159
/**
111
160
* The delta between min and max value
112
161
*
@@ -189,8 +238,8 @@ angular.module('rzModule', [])
189
238
190
239
$timeout ( function ( )
191
240
{
192
- self . setPointers ( ) ;
193
- self . adjustLabels ( ) ;
241
+ self . updateHandles ( 'both' ) ;
242
+ self . adjustLabels ( 'timeout' ) ;
194
243
self . bindToInputEvents ( ) ;
195
244
} ) ;
196
245
@@ -200,17 +249,17 @@ angular.module('rzModule', [])
200
249
// Watch for changes to the model
201
250
this . scope . $watch ( this . refLow , function ( )
202
251
{
203
- self . setPointers ( ) ;
204
- self . adjustLabels ( ) ;
252
+ self . updateHandles ( 'low' ) ;
253
+ self . adjustLabels ( 'refLow' ) ;
205
254
} ) ;
206
255
207
256
if ( this . range )
208
257
{
209
258
// We have to watch it only for range slider
210
259
this . scope . $watch ( this . refHigh , function ( )
211
260
{
212
- self . setPointers ( ) ;
213
- self . adjustLabels ( ) ;
261
+ self . updateHandles ( 'high' ) ;
262
+ self . adjustLabels ( 'refHigh' ) ;
214
263
} ) ;
215
264
}
216
265
@@ -220,8 +269,8 @@ angular.module('rzModule', [])
220
269
this . scope . $watch ( 'rzSliderFloor' , function ( )
221
270
{
222
271
self . setMinAndMax ( ) ;
223
- self . setPointers ( ) ;
224
- self . adjustLabels ( ) ;
272
+ self . updateHandles ( 'both' ) ;
273
+ self . adjustLabels ( 'floor' ) ;
225
274
} ) ;
226
275
}
227
276
@@ -231,8 +280,8 @@ angular.module('rzModule', [])
231
280
this . scope . $watch ( 'rzSliderCeil' , function ( )
232
281
{
233
282
self . setMinAndMax ( ) ;
234
- self . setPointers ( ) ;
235
- self . adjustLabels ( ) ;
283
+ self . updateHandles ( 'both' ) ;
284
+ self . adjustLabels ( 'ceil' ) ;
236
285
} ) ;
237
286
}
238
287
} ,
@@ -308,6 +357,7 @@ angular.module('rzModule', [])
308
357
this . minOffset = 0 ;
309
358
this . maxOffset = this . barWidth - pointerWidth ;
310
359
this . offsetRange = this . maxOffset - this . minOffset ;
360
+ this . setLeft ( this . ceilBub , this . barWidth - this . offsetWidth ( this . ceilBub ) ) ;
311
361
} ,
312
362
313
363
/**
@@ -317,26 +367,25 @@ angular.module('rzModule', [])
317
367
*/
318
368
setPointers : function ( )
319
369
{
320
- var newHighValue , newLowValue , minPtrOL , maxPtrOL , selBarOL , selBarWidth ;
370
+ var minPtrOL , maxPtrOL , selBarOL , selBarWidth ;
321
371
322
- this . setLeft ( this . ceilBub , this . barWidth - this . offsetWidth ( this . ceilBub ) ) ;
323
- newLowValue = this . percentValue ( this . scope [ this . refLow ] ) ;
372
+ this . lowValOffsetPerc = this . percentValue ( this . scope [ this . refLow ] ) ;
324
373
// Set low value slider handle position
325
- minPtrOL = this . setLeft ( this . minPtr , this . percentToOffset ( newLowValue ) ) ;
374
+ minPtrOL = this . setLeft ( this . minPtr , this . percentToOffset ( this . lowValOffsetPerc ) ) ;
326
375
// Set low value label position
327
376
this . setLeft ( this . lowBub , minPtrOL - this . halfOffsetWidth ( this . lowBub ) + this . ptrHalfWidth ) ;
328
377
329
378
if ( this . range )
330
379
{
331
- newHighValue = this . percentValue ( this . scope [ this . refHigh ] ) ;
380
+ this . highValOffsetPerc = this . percentValue ( this . scope [ this . refHigh ] ) ;
332
381
// Set high value slider handle position
333
- maxPtrOL = this . setLeft ( this . maxPtr , this . percentToOffset ( newHighValue ) ) ;
382
+ maxPtrOL = this . setLeft ( this . maxPtr , this . percentToOffset ( this . highValOffsetPerc ) ) ;
334
383
// Set high value slider handle label position
335
384
this . setLeft ( this . highBub , maxPtrOL - ( this . halfOffsetWidth ( this . highBub ) ) + this . ptrHalfWidth ) ;
336
385
337
386
// Set selection bar position
338
387
selBarOL = this . setLeft ( this . selBar , minPtrOL + this . ptrHalfWidth ) ;
339
- selBarWidth = this . percentToOffset ( newHighValue - newLowValue ) ;
388
+ selBarWidth = this . percentToOffset ( this . highValOffsetPerc - this . lowValOffsetPerc ) ;
340
389
this . selBar . css ( { width : selBarWidth + 'px' } ) ;
341
390
342
391
// Set combined label position
@@ -348,13 +397,94 @@ angular.module('rzModule', [])
348
397
}
349
398
} ,
350
399
400
+ /**
401
+ * Update slider handles and label positions
402
+ *
403
+ * @param {string } which
404
+ */
405
+ updateHandles : function ( which )
406
+ {
407
+ if ( which === 'low' )
408
+ {
409
+ this . updateLowHandle ( ) ;
410
+ if ( this . range ) { this . updateSelectionBar ( ) ; }
411
+ return ;
412
+ }
413
+
414
+ if ( which === 'high' )
415
+ {
416
+ this . updateHighHandle ( ) ;
417
+ if ( this . range ) { this . updateSelectionBar ( ) ; }
418
+ return ;
419
+ }
420
+
421
+ // Update both
422
+ this . updateLowHandle ( ) ;
423
+ this . updateHighHandle ( ) ;
424
+ this . updateSelectionBar ( ) ;
425
+ } ,
426
+
427
+ /**
428
+ * Update low slider handle position and label
429
+ *
430
+ * @returns {undefined }
431
+ */
432
+ updateLowHandle : function ( )
433
+ {
434
+ var minPtrOL ;
435
+
436
+ this . lowValOffsetPerc = this . percentValue ( this . scope [ this . refLow ] ) ;
437
+ // Set low value slider handle position
438
+ minPtrOL = this . setLeft ( this . minPtr , this . percentToOffset ( this . lowValOffsetPerc ) ) ;
439
+
440
+ // Set low value label position
441
+ this . setLeft ( this . lowBub , minPtrOL - this . halfOffsetWidth ( this . lowBub ) + this . ptrHalfWidth ) ;
442
+ } ,
443
+
444
+ /**
445
+ * Update high slider handle position and label
446
+ *
447
+ * @returns {undefined }
448
+ */
449
+ updateHighHandle : function ( )
450
+ {
451
+ var maxPtrOL ;
452
+
453
+ this . highValOffsetPerc = this . percentValue ( this . scope [ this . refHigh ] ) ;
454
+ // Set high value slider handle position
455
+ maxPtrOL = this . setLeft ( this . maxPtr , this . percentToOffset ( this . highValOffsetPerc ) ) ;
456
+ // Set high value slider handle label position
457
+ this . setLeft ( this . highBub , maxPtrOL - ( this . halfOffsetWidth ( this . highBub ) ) + this . ptrHalfWidth ) ;
458
+ } ,
459
+
460
+ /**
461
+ * Update slider selection bar, combined label and range label
462
+ */
463
+ updateSelectionBar : function ( )
464
+ {
465
+ var selBarOL , selBarWidth ;
466
+
467
+ // Set selection bar position
468
+ selBarOL = this . setLeft ( this . selBar , this . percentToOffset ( this . lowValOffsetPerc ) + this . ptrHalfWidth ) ;
469
+ selBarWidth = this . percentToOffset ( this . highValOffsetPerc - this . lowValOffsetPerc ) ;
470
+ this . selBar . css ( { width : selBarWidth + 'px' } ) ;
471
+
472
+ // Set combined label position
473
+ this . setLeft ( this . cmbBub , selBarOL + selBarWidth / 2 - this . halfOffsetWidth ( this . cmbBub ) + 1 ) ;
474
+
475
+ // Set range label position
476
+ this . setLeft ( this . selBub , selBarOL + selBarWidth / 2 - this . halfOffsetWidth ( this . selBub ) + 1 ) ;
477
+ this . scope . rzSliderDiff = this . roundStep ( this . scope [ this . refHigh ] - this . scope [ this . refLow ] ) ;
478
+ } ,
479
+
351
480
/**
352
481
* Adjust label positions and visibility
353
482
*
354
483
* @returns {undefined }
355
484
*/
356
485
adjustLabels : function ( )
357
486
{
487
+ // console.log('al', this.scope.$id + ' ' + arguments[0]);
358
488
var bubToAdjust = this . highBub ;
359
489
360
490
this . fitToBar ( this . lowBub ) ;
@@ -593,34 +723,49 @@ angular.module('rzModule', [])
593
723
*/
594
724
onStart : function ( pointer , ref , event )
595
725
{
726
+ var which ;
727
+
596
728
if ( this . tracking !== '' ) { return }
597
729
598
730
this . tracking = ref ;
599
731
732
+ switch ( ref )
733
+ {
734
+ case 'rzSliderModel' :
735
+ case 'rzSliderLow' :
736
+ which = 'low' ;
737
+ break ;
738
+
739
+ case 'rzSliderHigh' :
740
+ which = 'high' ;
741
+ break ;
742
+ }
743
+
600
744
pointer . addClass ( 'active' ) ;
601
745
602
746
event . stopPropagation ( ) ;
603
747
event . preventDefault ( ) ;
604
748
605
749
if ( event . touches )
606
750
{
607
- $document . on ( 'touchmove' , angular . bind ( this , this . onMove ) ) ;
751
+ $document . on ( 'touchmove' , angular . bind ( this , this . onMove , which ) ) ;
608
752
$document . on ( 'touchend' , angular . bind ( this , this . onEnd , pointer ) ) ;
609
753
}
610
754
else
611
755
{
612
- $document . on ( 'mousemove' , angular . bind ( this , this . onMove ) ) ;
756
+ $document . on ( 'mousemove' , angular . bind ( this , this . onMove , which ) ) ;
613
757
$document . on ( 'mouseup' , angular . bind ( this , this . onEnd , pointer ) ) ;
614
758
}
615
759
} ,
616
760
617
761
/**
618
762
* onMove event handler
619
763
*
620
- * @param {Event } event The event
764
+ * @param {string } ref
765
+ * @param {Event } event The event
621
766
* @returns {undefined }
622
767
*/
623
- onMove : function ( event )
768
+ onMove : function ( ref , event )
624
769
{
625
770
var eventX = event . clientX || event . touches [ 0 ] . clientX ,
626
771
newOffset , newPercent , newValue ;
@@ -648,8 +793,8 @@ angular.module('rzModule', [])
648
793
}
649
794
650
795
this . scope [ this . tracking ] = this . roundStep ( newValue ) ;
651
- this . setPointers ( ) ;
652
- this . adjustLabels ( ) ;
796
+ this . updateHandles ( ref ) ;
797
+ this . adjustLabels ( 'onMove' ) ;
653
798
this . scope . $apply ( ) ;
654
799
} ,
655
800
@@ -677,9 +822,10 @@ angular.module('rzModule', [])
677
822
678
823
this . tracking = '' ;
679
824
}
680
-
681
825
} ;
682
826
827
+ Slider . prototype . adjustLabels = throttle ( Slider . prototype . adjustLabels , 350 ) ;
828
+
683
829
return Slider ;
684
830
} ] )
685
831
0 commit comments