1
1
import _ from 'lodash' ;
2
2
import PropTypes from 'prop-types' ;
3
3
import React from 'react' ;
4
- import { StyleSheet , PanResponder , ViewPropTypes , AccessibilityInfo } from 'react-native' ;
4
+ import {
5
+ StyleSheet ,
6
+ PanResponder ,
7
+ ViewPropTypes ,
8
+ AccessibilityInfo ,
9
+ Animated
10
+ } from 'react-native' ;
5
11
import { Constants } from '../../helpers' ;
6
12
import { PureBaseComponent } from '../../commons' ;
7
13
import { Colors } from '../../style' ;
@@ -107,6 +113,7 @@ export default class Slider extends PureBaseComponent {
107
113
containerSize : { width : 0 , height : 0 } ,
108
114
trackSize : { width : 0 , height : 0 } ,
109
115
thumbSize : { width : 0 , height : 0 } ,
116
+ thumbActiveAnimation : new Animated . Value ( 1 ) ,
110
117
measureCompleted : false
111
118
} ;
112
119
@@ -116,6 +123,10 @@ export default class Slider extends PureBaseComponent {
116
123
this . _minTrackStyles = { style : { } } ;
117
124
this . _x = 0 ;
118
125
this . _dx = 0 ;
126
+ this . _thumbAnimationConstants = {
127
+ duration : 100 ,
128
+ defaultScaleFactor : 1.5
129
+ } ;
119
130
120
131
this . initialValue = this . getRoundedValue ( props . value ) ;
121
132
this . initialThumbSize = THUMB_SIZE ;
@@ -244,11 +255,28 @@ export default class Slider extends PureBaseComponent {
244
255
const style = thumbStyle || styles . thumb ;
245
256
const activeStyle = activeThumbStyle || styles . activeThumb ;
246
257
247
- this . _thumbStyles . style = ! this . props . disabled && ( start ? activeStyle : style ) ;
258
+ const activeOrInactiveStyle = ! this . props . disabled && ( start ? activeStyle : style ) ;
259
+ this . _thumbStyles . style = _ . omit ( activeOrInactiveStyle , 'height' , 'width' ) ;
248
260
this . thumb . setNativeProps ( this . _thumbStyles ) ;
261
+ this . scaleThumb ( start ) ;
249
262
}
250
263
}
251
264
265
+ scaleThumb = start => {
266
+ const scaleFactor = start ? this . calculatedThumbActiveScale ( ) : 1 ;
267
+ this . thumbAnimationAction ( scaleFactor ) ;
268
+ }
269
+
270
+ thumbAnimationAction = ( toValue ) => {
271
+ const { thumbActiveAnimation} = this . state ;
272
+ const { duration} = this . _thumbAnimationConstants ;
273
+ Animated . timing ( thumbActiveAnimation , {
274
+ toValue,
275
+ duration,
276
+ useNativeDriver : true
277
+ } ) . start ( ) ;
278
+ }
279
+
252
280
getRoundedValue ( value ) {
253
281
const { step} = this . props ;
254
282
const v = this . getValueInRange ( value ) ;
@@ -297,6 +325,37 @@ export default class Slider extends PureBaseComponent {
297
325
this . thumb = r ;
298
326
} ;
299
327
328
+ shouldDoubleSizeByDefault = ( ) => {
329
+ const { activeThumbStyle, thumbStyle} = this . props ;
330
+ return ! activeThumbStyle || ! thumbStyle ;
331
+ }
332
+
333
+ calculatedThumbActiveScale = ( ) => {
334
+ const { activeThumbStyle, thumbStyle, disabled, disableActiveStyling} = this . props ;
335
+ if ( disabled || disableActiveStyling ) {
336
+ return 1 ;
337
+ }
338
+
339
+ const { defaultScaleFactor} = this . _thumbAnimationConstants ;
340
+ if ( this . shouldDoubleSizeByDefault ( ) ) {
341
+ return defaultScaleFactor ;
342
+ }
343
+
344
+ const scaleRatioFromSize = activeThumbStyle . height / thumbStyle . height ;
345
+ return scaleRatioFromSize || defaultScaleFactor ;
346
+ } ;
347
+
348
+ updateTrackStepAndStyle = ( { nativeEvent} ) => {
349
+ this . _x = nativeEvent . locationX ;
350
+ this . updateValue ( nativeEvent . locationX ) ;
351
+
352
+ if ( this . props . step > 0 ) {
353
+ this . bounceToStep ( ) ;
354
+ } else {
355
+ this . updateStyles ( nativeEvent . locationX ) ;
356
+ }
357
+ }
358
+
300
359
/* Events */
301
360
302
361
onValueChange = value => {
@@ -323,6 +382,15 @@ export default class Slider extends PureBaseComponent {
323
382
this . handleMeasure ( 'thumbSize' , nativeEvent ) ;
324
383
} ;
325
384
385
+ handleTrackPress = ( { nativeEvent} ) => {
386
+ if ( this . props . disabled ) {
387
+ return ;
388
+ }
389
+
390
+ this . updateTrackStepAndStyle ( { nativeEvent} ) ;
391
+ this . onSeekEnd ( ) ;
392
+ } ;
393
+
326
394
handleMeasure = ( name , nativeEvent ) => {
327
395
const { width, height} = nativeEvent . layout ;
328
396
const size = { width, height} ;
@@ -368,16 +436,48 @@ export default class Slider extends PureBaseComponent {
368
436
_ . invoke ( AccessibilityInfo , 'announceForAccessibility' , `New value ${ newValue } ` ) ;
369
437
} ;
370
438
439
+ thumbHitSlop = { top : 10 , bottom : 10 , left : 24 , right : 24 } ;
440
+
371
441
/* Renders */
372
442
443
+ renderThumb = ( ) => {
444
+ const {
445
+ thumbStyle,
446
+ disabled,
447
+ thumbTintColor
448
+ } = this . getThemeProps ( ) ;
449
+ return (
450
+ < Animated . View
451
+ hitSlop = { this . thumbHitSlop }
452
+ ref = { this . setThumbRef }
453
+ onLayout = { this . onThumbLayout }
454
+ { ...this . _panResponder . panHandlers }
455
+ style = { [
456
+ styles . thumb ,
457
+ thumbStyle ,
458
+ {
459
+ backgroundColor : disabled
460
+ ? DEFAULT_COLOR
461
+ : thumbTintColor || ACTIVE_COLOR
462
+ } ,
463
+ {
464
+ transform : [
465
+ {
466
+ scale : this . state . thumbActiveAnimation
467
+ }
468
+ ]
469
+ }
470
+ ] }
471
+ />
472
+ ) ;
473
+ }
474
+
373
475
render ( ) {
374
476
const {
375
477
containerStyle,
376
- thumbStyle,
377
478
trackStyle,
378
479
renderTrack,
379
480
disabled,
380
- thumbTintColor,
381
481
minimumTrackTintColor = ACTIVE_COLOR ,
382
482
maximumTrackTintColor = DEFAULT_COLOR
383
483
} = this . getThemeProps ( ) ;
@@ -427,18 +527,9 @@ export default class Slider extends PureBaseComponent {
427
527
/>
428
528
</ View >
429
529
) }
430
- < View
431
- ref = { this . setThumbRef }
432
- onLayout = { this . onThumbLayout }
433
- style = { [
434
- styles . thumb ,
435
- thumbStyle ,
436
- {
437
- backgroundColor : disabled ? DEFAULT_COLOR : thumbTintColor || ACTIVE_COLOR
438
- }
439
- ] }
440
- />
441
- < View style = { styles . touchArea } { ...this . _panResponder . panHandlers } />
530
+
531
+ < View style = { styles . touchArea } onTouchEnd = { this . handleTrackPress } />
532
+ { this . renderThumb ( ) }
442
533
</ View >
443
534
) ;
444
535
}
@@ -474,7 +565,7 @@ const styles = StyleSheet.create({
474
565
width : THUMB_SIZE + 16 ,
475
566
height : THUMB_SIZE + 16 ,
476
567
borderRadius : ( THUMB_SIZE + 16 ) / 2 ,
477
- borderWidth : BORDER_WIDTH + 6
568
+ borderWidth : BORDER_WIDTH
478
569
} ,
479
570
touchArea : {
480
571
...StyleSheet . absoluteFillObject ,
0 commit comments