import React, { Component } from 'react'; import { Animated, Dimensions, StyleSheet } from 'react-native'; import { PanGestureHandler, TapGestureHandler, ScrollView, State, PanGestureHandlerGestureEvent, TapGestureHandlerStateChangeEvent, } from 'react-native-gesture-handler'; import { USE_NATIVE_DRIVER } from '../../config'; import { LoremIpsum } from '../../common'; const windowWidth = Dimensions.get('window').width; const circleRadius = 30; type Props = { tapRef: React.RefObject; panRef: React.RefObject; }; export class TapOrPan extends Component { private touchX: Animated.Value; private translateX: Animated.AnimatedAddition; private onPanGestureEvent: (event: PanGestureHandlerGestureEvent) => void; constructor(props: Props) { super(props); this.touchX = new Animated.Value(windowWidth / 2 - circleRadius); this.translateX = Animated.add( this.touchX, new Animated.Value(-circleRadius) ); this.onPanGestureEvent = Animated.event( [ { nativeEvent: { x: this.touchX, }, }, ], { useNativeDriver: USE_NATIVE_DRIVER } ); } private onTapHandlerStateChange = ({ nativeEvent, }: TapGestureHandlerStateChangeEvent) => { if (nativeEvent.oldState === State.ACTIVE) { // Once tap happened we set the position of the circle under the tapped spot this.touchX.setValue(nativeEvent.x); } }; render() { const { tapRef, panRef } = this.props; return ( ); } } export default class Example extends Component { render() { const tapRef = React.createRef(); const panRef = React.createRef(); return ( ); } } const styles = StyleSheet.create({ horizontalPan: { backgroundColor: '#f48fb1', height: 150, justifyContent: 'center', marginVertical: 10, }, circle: { backgroundColor: '#42a5f5', borderRadius: circleRadius, height: circleRadius * 2, width: circleRadius * 2, }, wrapper: { flex: 1, }, });