I am trying to get a handle on understanding how to use Panresponder. I am trying to create a 'cross hairs' that show up wherever the user clicks. I'd like to be able to have it follow the users finger but right now I cant even get it working to show up right where the user taps. Right now its sort of working but the X,Y values are off. I cant understand what I am doing wrong.
I set the initial offset to x:0 and y:0 because I do not care where the previous user clicked. I've tried every combination of using locationX/locationY or pageX/pageY, or gesture.x0/gesture.y0.
Even weirder, after Ive made at least one click in the box that contains the panhandlers, I can then click below the box to initiate the panhandlers. If I click out of the box before clicking inside the box for the first time, the panhandlers wont get called.
Any help would be amazing
Main file
import Line from '../components/Line';
const {width, height} = Dimensions.get('window');
const PanResponderComp = () => {
const pan = useState(new Animated.ValueXY())[0];
const [opacity, setOpacity] = useState(0);
const panResponder = useState(
PanResponder.create({
onStartShouldSetPanResponder: () => true,
// onMoveShouldSetPanResponder: () => true,
onPanResponderGrant: (e, gesture) => {
const {locationX, locationY} = e.nativeEvent;
console.log(locationX);
console.log(locationY);
pan.setOffset({x: 0, y: 0});
pan.setValue({
x: locationX,
y: locationY,
});
setOpacity(1);
},
// onPanResponderMove: (e, gesture) => {
// pan.x.setValue(gesture.dx);
// pan.y.setValue(gesture.dy);
// },
onPanResponderRelease: () => {
console.log('RELEASED');
// pan.flattenOffset();
setOpacity(0);
},
}),
)[0];
return (
<View style={styles.container}>
<View style={styles.chartContainer}>
<Animated.View
{...panResponder.panHandlers}
style={[
{borderWidth: 2, borderColor: 'green'},
StyleSheet.absoluteFill,
]}>
<Animated.View
style={{
transform: [{translateX: pan.x}],
opacity: opacity,
...StyleSheet.absoluteFill,
}}>
<Line y={height} x={0} />
</Animated.View>
<Animated.View
style={{
transform: [{translateY: pan.y}],
opacity: opacity,
...StyleSheet.absoluteFill,
}}>
<Line x={width} y={0} />
</Animated.View>
</Animated.View>
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
},
titleText: {
fontSize: 14,
lineHeight: 24,
fontWeight: 'bold',
},
chartContainer: {
width: 400,
height: 400,
borderWidth: 1,
borderColor: 'orange',
},
});
export default PanResponderComp;
Line.js
import React from 'react';
import {View, Text, StyleSheet} from 'react-native';
import Svg, {Line} from 'react-native-svg';
export default ({x, y}) => {
// console.log(vertical);
return (
<Svg>
<Line
x1={'0'}
x2={x}
y1={'0'}
y2={y}
stroke={'black'}
strokeWidth={'2'}
strokeDasharray="6 6"
/>
</Svg>
);
};
Figured it out. The Animated.View I have wrapped in both components didn't have a set width/height so it was inheriting it from the container. This meant I could see the dash lines but there was really a giant box I was moving around. Once I set the height/width on each Animated.View I was able to get the click to be spot on
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.