@@ -14,12 +14,6 @@ import {
1414 SafeAreaView ,
1515 Platform ,
1616} from 'react-native' ;
17- import {
18- GestureDetector ,
19- Gesture ,
20- GestureStateChangeEvent ,
21- gestureHandlerRootHOC ,
22- } from 'react-native-gesture-handler' ;
2317import { ImageComponentOptionalProps , ImageComponentProps , ImageComponentState } from './types' ;
2418
2519const SCREEN_WIDTH = Dimensions . get ( 'window' ) . width ;
@@ -43,6 +37,7 @@ class ImageComponent extends React.Component<ImageComponentProps, ImageComponent
4337 private _lastScale : number = 1 ;
4438
4539 private _isGestureMoved : boolean = false ;
40+ private _lastTap : number = 0 ;
4641
4742 constructor ( props : ImageComponentProps ) {
4843 super ( props ) ;
@@ -71,15 +66,27 @@ class ImageComponent extends React.Component<ImageComponentProps, ImageComponent
7166 onPanResponderTerminate : onPanEnd ,
7267 onPanResponderRelease : onPanEnd ,
7368 onPanResponderMove : onPanMove ,
69+
70+ onPanResponderGrant : this . _onPanResponderGrant ,
7471 } ) ;
7572 }
7673
7774 private _onShouldSetPanResponder ( evt : GestureResponderEvent ) {
78- return evt . nativeEvent . touches . length === 1 ;
75+ return evt . nativeEvent . touches . length <= 2 ;
76+ }
77+
78+ private _onPanResponderGrant = ( _evt : any , gesture : PanResponderGestureState ) => {
79+ if ( gesture . numberActiveTouches === 2 ) {
80+ this . _debug ( '_onPanResponderGrant' , gesture ) ;
81+ }
7982 }
8083
8184 private _onPanResponderMove ( _evt : any , gesture : PanResponderGestureState ) {
8285 this . _debug ( '_onPanResponderMove' , 'dx' , gesture . dx , 'dy' , gesture . dy , this . _lastOffset ) ;
86+ if ( gesture . numberActiveTouches === 2 ) {
87+ return ;
88+ }
89+
8390 this . _isGestureMoved = true ;
8491
8592 if ( this . _lastScale > this . _getMinimumScale ( ) ) {
@@ -111,7 +118,22 @@ class ImageComponent extends React.Component<ImageComponentProps, ImageComponent
111118 this . props . onZoomStateChange ( true ) ;
112119 this . _translateXY . setValue ( { x : 0 , y : Math . max ( 0 , gesture . dy ) } ) ;
113120 }
114- private _onPanResponderEnd ( _evt : any , gesture : PanResponderGestureState ) {
121+ private _onPanResponderEnd ( _evt : GestureResponderEvent , gesture : PanResponderGestureState ) {
122+ this . _debug ( '_onPanResponderEnd' , 'gesture.numberActiveTouches' , gesture . numberActiveTouches ) ;
123+ if ( gesture . numberActiveTouches === 0 ) {
124+ this . _debug ( '_onPanResponderEnd' , 'gesture.dx' , gesture . dx , 'gesture.dy' , gesture . dy ) ;
125+ if ( Math . abs ( gesture . dx ) < 10 && Math . abs ( gesture . dy ) < 10 ) {
126+ this . _handleTap ( {
127+ x : gesture . x0 ,
128+ y : gesture . y0
129+ } ) ;
130+
131+ return ;
132+ }
133+ } else if ( gesture . numberActiveTouches === 2 ) {
134+ return ;
135+ }
136+
115137 if ( ! this . _isGestureMoved ) {
116138 return ;
117139 }
@@ -156,7 +178,7 @@ class ImageComponent extends React.Component<ImageComponentProps, ImageComponent
156178 private _getMaximumScale = ( ) : number => 2.5 ;
157179 private _getMinimumScale = ( ) : number => 1.0 ;
158180
159- private _handleImageZoomInOut = ( evt : GestureStateChangeEvent < any > ) => {
181+ private _handleImageZoomInOut = ( evt : { x : number ; y : number } ) => {
160182 this . _debug ( 'double tab triggered' , '_scaleNum' , this . _lastScale , evt , 'ratio' , this . _getRatio ( ) ) ;
161183
162184 if ( this . _lastScale > this . _getMinimumScale ( ) ) {
@@ -234,6 +256,19 @@ class ImageComponent extends React.Component<ImageComponentProps, ImageComponent
234256 }
235257 } ;
236258
259+ private _handleTap = ( tapCoords : { x : number ; y : number } ) => {
260+ const now = ( new Date ( ) ) . getTime ( ) ;
261+ const delta = now - this . _lastTap ;
262+
263+ this . _debug ( '_handleTap' , '_lastTap' , this . _lastTap , 'delta' , delta ) ;
264+ if ( delta <= 500 ) {
265+ // double tap
266+ this . _handleImageZoomInOut ( tapCoords ) ;
267+ }
268+
269+ this . _lastTap = now ;
270+ } ;
271+
237272 private _getRatio = ( ) =>
238273 this . state . width
239274 ? this . state . width >= SCREEN_WIDTH
@@ -368,19 +403,6 @@ class ImageComponent extends React.Component<ImageComponentProps, ImageComponent
368403 return < Animated . View style = { footerAnim } > { innerComponent } </ Animated . View > ;
369404 } ;
370405
371- private _gestureDoubleTap = ( ) => Gesture . Tap ( ) . maxDuration ( 250 ) . numberOfTaps ( 2 ) . onStart ( ( evt ) => {
372- this . _debug ( '_gestureDoubleTap' , 'onStart' ) ;
373- this . _handleImageZoomInOut ( evt ) ;
374- this . _debug ( '_gestureDoubleTap' , 'this._handleImageZoomInOut' , '-> ok' ) ;
375- } ) ;
376- private _gesturePinch = ( ) => Gesture . Pinch ( ) . onEnd ( ( evt ) => {
377- this . _debug ( '_gesturePinch' , 'onEnd' ) ;
378- this . _onPinchEnd ( evt ) ;
379- } ) . onUpdate ( ( evt ) => {
380- this . _debug ( '_gesturePinch' , 'onUpdate' , evt ) ;
381- this . _onPinchUpdate ( evt ) ;
382- } ) ;
383-
384406 static getDerivedStateFromProps (
385407 nextProps : Readonly < ImageComponentProps > ,
386408 prevState : Readonly < ImageComponentState >
@@ -450,9 +472,7 @@ class ImageComponent extends React.Component<ImageComponentProps, ImageComponent
450472 style = { moveObjStyle }
451473 { ...( this . state . isZooming || Platform . OS === 'ios' ? this . _panResponder . panHandlers : { } ) }
452474 renderToHardwareTextureAndroid >
453- < GestureDetector gesture = { Gesture . Exclusive ( this . _gestureDoubleTap ( ) , this . _gesturePinch ( ) ) } >
454475 < RNImage source = { this . props . source } style = { computeImageStyle } onLoadEnd = { this . _onImageLoadEnd } />
455- </ GestureDetector >
456476 </ Animated . View >
457477 < SafeAreaView style = { styles . safeAreaContainer } pointerEvents = "none" >
458478 { this . _renderHeader ( ) }
@@ -496,6 +516,4 @@ const styles = StyleSheet.create({
496516 } ,
497517} ) ;
498518
499- const Image = gestureHandlerRootHOC ( ( props : ImageComponentProps ) => < ImageComponent { ...props } /> ) ;
500-
501- export default Image ;
519+ export default ImageComponent ;
0 commit comments