简体   繁体   中英

PanResponder X,Y values slightly off on react native app

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>
  );
};

PanResponder 演示

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM