11import React , { Component } from 'react'
2- import PropTypes from 'prop-types'
32import {
43 View ,
54 StyleSheet ,
65 Text ,
7- TouchableWithoutFeedback ,
8- PanResponder ,
96 Animated ,
107} from 'react-native'
118
9+ import {
10+ PanGestureHandler ,
11+ TapGestureHandler ,
12+ State ,
13+ } from 'react-native-gesture-handler' ;
14+
15+
1216const DefaultColors = {
1317 valueColor : '#999' ,
1418 trackBackgroundColor : '#DDD' ,
@@ -64,6 +68,23 @@ export default class extends Component {
6468 startingNumberValue : props . value ,
6569 } ;
6670
71+
72+ this . _translateX = new Animated . Value ( 0 ) ;
73+ this . _translateY = new Animated . Value ( 0 ) ;
74+
75+ this . _lastOffset = { x : 0 , y : 0 } ;
76+ this . _onGestureEvent = Animated . event (
77+ [
78+ {
79+ nativeEvent : {
80+ translationX : this . _translateX ,
81+ translationY : this . _translateY ,
82+ } ,
83+ } ,
84+ ] ,
85+ { useNativeDriver : false }
86+ ) ;
87+
6788 this . initiateAnimator ( ) ;
6889
6990 }
@@ -72,7 +93,7 @@ export default class extends Component {
7293 }
7394
7495 componentWillUnmount ( ) {
75- this . animatedValue . removeAllListeners ( ) ;
96+ this . _translateX . removeAllListeners ( ) ;
7697 }
7798
7899 scaleUp = ( ) => {
@@ -89,52 +110,46 @@ export default class extends Component {
89110 } ) . start ( ) ;
90111 }
91112
92- createPanHandler = ( ) => PanResponder . create ( {
93- onPanResponderTerminationRequest : ( ) => false ,
94- onStartShouldSetPanResponder : ( event , gestureState ) => true ,
95- onMoveShouldSetPanResponder : ( event , gestureState ) => true ,
96- onPanResponderGrant : ( event , gestureState ) => {
113+ _onHandlerStateChange = event => {
114+
115+ if ( event . nativeEvent . state === State . BEGAN ) {
97116 const { totalDuration, value } = this . props ;
98117 const currentPercent = totalDuration !== 0 ? Math . min ( totalDuration , value ) / totalDuration : 0
99118 const initialX = currentPercent * this . state . dimensionWidth
100119 const boundedX = Math . min ( Math . max ( initialX , 0 ) , this . state . dimensionWidth - TrackSliderSize ) ;
101120
102- this . lastDx = 0
103121 this . panResonderMoved = false ;
104122
105- this . animatedValue . setOffset ( {
106- x : boundedX ,
107- y : 0
108- } )
109- this . animatedValue . setValue ( {
110- x : 0 ,
111- y : 0
112- } )
123+ this . _lastOffset . x = boundedX
113124
114125 this . setState ( { scrubbing : true } , this . scaleUp ) ;
115- } ,
116- onPanResponderMove : ( evt , gestureState ) => {
126+ } else if ( event . nativeEvent . state === State . ACTIVE ) {
117127 this . panResonderMoved = true ;
118- const stepValue = ( gestureState . dx - this . lastDx ) * this . state . scrubRate ;
119- this . lastDx = gestureState . dx
120- const newDxValue = this . animatedValue . x . _value + ( stepValue ) ;
121- this . animatedValue . setValue ( { x : newDxValue , y : gestureState . dy } )
122- } ,
123- onPanResponderRelease : ( evt , gestureState ) => {
128+ this . _lastOffset . x += event . nativeEvent . translationX ;
129+ this . _lastOffset . y += event . nativeEvent . translationY ;
130+ this . _translateX . setOffset ( this . _lastOffset . x ) ;
131+ this . _translateX . setValue ( 0 ) ;
132+ this . _translateY . setOffset ( this . _lastOffset . y ) ;
133+ this . _translateY . setValue ( 0 ) ;
134+ } else if ( event . nativeEvent . state === State . END ) {
124135 const { dimensionWidth } = this . state ;
125136 const { totalDuration } = this . props ;
126137
127- const boundedX = Math . min ( Math . max ( this . value . x , 0 ) , dimensionWidth ) ;
138+ this . _lastOffset . x = this . _lastOffset . x + this . _translateX . _value
139+
140+ const boundedX = Math . min ( Math . max ( this . _lastOffset . x , 0 ) , dimensionWidth ) ;
128141
129142 const percentScrubbed = boundedX / dimensionWidth ;
130143 const scrubbingValue = percentScrubbed * totalDuration
131144
132145 if ( this . panResonderMoved ) {
133146 this . onSlidingComplete ( scrubbingValue )
134147 }
148+
135149 this . setState ( { scrubbing : false , scrubRate : 1 } , this . scaleDown ) ;
150+
136151 }
137- } )
152+ } ;
138153
139154 formattedStartingNumber = ( ) => {
140155 const { scrubbing, startingNumberValue } = this . state ;
@@ -210,23 +225,15 @@ export default class extends Component {
210225 }
211226
212227 initiateAnimator = ( ) => {
213-
214- this . animatedValue = new Animated . ValueXY ( { x : 0 , y : 0 } )
215- this . value = { x : 0 , y : 0 }
216- this . lastDx = 0
217-
218- this . animatedValue . addListener ( ( value ) => {
219- const boundedValue = Math . min ( Math . max ( value . x , 0 ) , this . state . dimensionWidth ) ;
228+ this . _translateX . addListener ( ( { value } ) => {
229+ const boundedValue = Math . min ( Math . max ( value , 0 ) , this . state . dimensionWidth ) ;
220230
221- this . handleScrubRateChange ( value ) ;
222-
223231 this . setState ( {
224232 startingNumberValue : ( boundedValue / this . state . dimensionWidth ) * this . props . totalDuration ,
225233 endingNumberValue : ( 1 - ( boundedValue / this . state . dimensionWidth ) ) * this . props . totalDuration
226234 } )
227- return this . value = value
235+ return ;
228236 } ) ;
229- this . panResponder = this . createPanHandler ( )
230237 }
231238
232239 render ( ) {
@@ -253,7 +260,6 @@ export default class extends Component {
253260 const progressPercent = totalDuration !== 0 ? cappedValue / totalDuration : 0 ;
254261 const displayPercent = progressPercent * ( dimensionWidth ) ;
255262 const progressWidth = progressPercent * 100
256-
257263 const bufferedProgressPercent = totalDuration !== 0 ? cappedBufferedValue / totalDuration : 0 ;
258264 const bufferedProgressWidth = bufferedProgressPercent * 100
259265
@@ -278,7 +284,7 @@ export default class extends Component {
278284 let boundX = progressPercent
279285
280286 if ( dimensionWidth ) {
281- boundX = this . animatedValue . x . interpolate ( {
287+ boundX = this . _translateX . interpolate ( {
282288 inputRange : [ 0 , dimensionWidth ] ,
283289 outputRange : [ 0 , dimensionWidth ] ,
284290 extrapolate : 'clamp'
@@ -309,32 +315,35 @@ export default class extends Component {
309315 style = { [
310316 styles . progressTrack ,
311317 { ...progressTrackStyle } ,
312- ! scrubbing
318+ ! scrubbing
313319 ? { width : `${ progressWidth } %` }
314320 : { width : boundX }
315-
316321 ] }
317322 />
318-
319- < Animated . View
320- key = 'progressTrack'
321- style = { [
322- styles . trackSlider ,
323- { ...scrubberColor } ,
324- // { left: progressPercent * dimensionWidth },
325-
326- ! scrubbing
327- ? { transform : [ { translateX : displayPercent } , scaleStyle ] }
328- : { transform : [ { translateX : boundX } , scaleStyle ] } ,
329-
330- ! scrubbing
331- ? { transform : [ { translateX : displayPercent } , scaleStyle ] }
332- : { transform : [ { translateX : boundX } , scaleStyle ] } ,
333-
334- ] }
335- { ...this . panResponder . panHandlers }
336- hitSlop = { { top : 50 , bottom : 50 , left : 50 , right : 50 } }
337- />
323+ < PanGestureHandler
324+ onGestureEvent = { this . _onGestureEvent }
325+ onHandlerStateChange = { this . _onHandlerStateChange }
326+ minDist = { 0 }
327+ >
328+ < Animated . View
329+ style = { [
330+ styles . trackSliderWrapper ,
331+ ! scrubbing
332+ ? { left : displayPercent - ( TrackSliderSize / 2 ) }
333+ : { transform : [ { translateX : boundX } ] } ,
334+ ] }
335+ hitSlop = { { top : 20 , bottom : 20 , left : 50 , right : 50 } }
336+ >
337+ < Animated . View
338+ key = 'progressTrack'
339+ style = { [
340+ styles . trackSlider ,
341+ { ...scrubberColor } ,
342+ { transform : [ scaleStyle ] } ,
343+ ] }
344+ />
345+ </ Animated . View >
346+ </ PanGestureHandler >
338347 </ View >
339348
340349 < View style = { styles . valuesContainer } >
@@ -387,12 +396,15 @@ const styles = StyleSheet.create({
387396 borderBottomLeftRadius : 3 ,
388397 zIndex : 1 ,
389398 } ,
399+ trackSliderWrapper : {
400+ zIndex : 3 ,
401+ position : 'absolute' ,
402+ left : 0 - ( TrackSliderSize / 2 ) ,
403+ } ,
390404 trackSlider : {
391405 width : TrackSliderSize ,
392406 height : TrackSliderSize ,
393407 borderRadius : TrackSliderSize ,
394408 borderColor : '#fff' ,
395- zIndex : 3 ,
396- position : 'absolute' ,
397409 }
398410} ) ;
0 commit comments