TouchableOpacity с PanResponder как родительский работает только иногда - PullRequest
0 голосов
/ 17 января 2020

Я перепробовал все и не могу заставить Touchable Opacity (кнопки «Согнутые») работать должным образом, они работают только иногда и в основном только в левой части экрана.

Они отлично работали, прежде чем я добавил PanResponder, но мне нужно, чтобы круг вращался. Основная особенность приложения - вращающееся «колесо» кнопок.

Кто-нибудь знает, что я делаю неправильно?

Вот код для HomeScreen:

import React, { Component } from 'react';
import {
  Modal,
  StyleSheet,
  View,
  Image,
  ImageBackground,
  TouchableHighlight,
  TouchableOpacity,
  Text,
  TouchableWithoutFeedback,
  Animated,
  Dimensions,
  Alert,
  PanResponder,
} from 'react-native';
import LogoTitle from './../modules/Header/LogoTitle.js';
import BendedButton from "./../assets/BendedButton.png";
import * as SQLite from 'expo-sqlite';

const db = SQLite.openDatabase("StressDatabase.db");

const FULL_WIDTH = Dimensions.get('window').width;
const FULL_HEIGHT = Dimensions.get('window').height;

export default class HomeScreen extends Component {
  constructor(props) {
    super(props);
    this.state = {
      Validated: null,
      relaxModalVisible: false,
      journalModalVisible: false,
      angle: 0,
      lastAngle: 0,
    };
}

fetchAuth() {
  db.transaction(tx => {
    tx.executeSql('SELECT validated FROM auth ORDER BY date_added DESC LIMIT 1', [], (tx, results) => {
      console.log(results.rows.item(0));
      var row = results.rows.item(0);
      if (results.rows.length != 0) {
        console.log('ROW: ', row.validated);
        this.setState({Validated: row.validated})
      } else {
        console.log('No rows in Database');
      }
    });
  });
}
  // Sets the title to LogoTitle (Oceaim Logo)
  static navigationOptions = {
    headerTitle: () => <LogoTitle />,
    headerStyle: { backgroundColor: '#4c454a' }
  };

  componentWillMount() {
    this._panResponder = PanResponder.create({
      onMoveShouldSetPanResponderCapture: (evt, gestureState) => !!this.setAngle(gestureState),
      onPanResponderMove: (e,gs) => {
        if (gs.dy > 30 || gs.dy < -30 || gs.dx > 30 || gs.dx < -30) {
          console.log("HIT!");
          this.setAngle(gs);
        }
        else {
          return;
        }
      },
      onPanResponderTerminationRequest: (evt, gestureState) => true,
      onShouldBlockNativeResponder: (evt, gestureState) => false,
    });
  }

  setAngle = ({moveX, moveY, dx, dy}) => {
    let xOrigin = this.props.xCenter - (this.props.dialRadius + this.props.btnRadius);
    let yOrigin = this.props.yCenter - (this.props.dialRadius + this.props.btnRadius);
    let a = this.cartesianToPolar(moveX-xOrigin, moveY-yOrigin, dx, dy);

    if (a<=this.props.min) {
      this.setState({angle: this.props.min});
    } else if (a>=this.props.max) {
      this.setState({angle: this.props.max});
    } else {
      this.setState({angle: a});
    }
  }

  cartesianToPolar(x,y, dx, dy) {
    if (dx > 30 || dx < -30 || dy < -30 || dy > 30) {

      let hC = this.props.dialRadius + this.props.btnRadius;

      if (x === 0) {
        return y>hC ? 0 : 180;
      }
      else if (y === 0) {
        return x>hC ? 90 : 270;
      }
      else {
        return (Math.round((Math.atan((y-hC)/(x-hC)))*180/Math.PI) +
          (x>hC ? 90 : 270));
      }
    }
  }

  // Runs before the screen is rendered
  componentDidMount(){
    db.transaction(tx => {
        tx.executeSql(
          'CREATE TABLE IF NOT EXISTS journals (id INTEGER PRIMARY KEY AUTOINCREMENT, date_added TEXT, symptom varchar(255), reason VARCHAR(255), solution VARCHAR(255), type VARCHAR(50))',
        );
        tx.executeSql(
          'CREATE TABLE IF NOT EXISTS auth (id INTEGER PRIMARY KEY AUTOINCREMENT, date_added TEXT, validated INT)',
          //'DROP TABLE IF EXISTS auth;',
        );
        console.log('Went trough')
      });

      this.subs = [
        this.props.navigation.addListener('didFocus', () => {
            this.fetchAuth();
        }),
      ];
  }

  componentWillUnmount() {
    this.subs.forEach(sub => sub.remove());
  }

_ScreenChange(screen) {
  this.setJournalModalVisible(false);
  this.setRelaxModalVisible(false);
 this.props.navigation.navigate(screen);
};

  isVerified() {
    if (this.state.Validated == 1) {
        this.setRelaxModalVisible(true);
    } else {
      Alert.alert(
        'Adgang nægtet!',
        'Du skal valideres før du kan bruge denne funtion. \n\nDette gør du under Support modulet.',
        [
          {
            text: 'Ok',
            onPress: () =>
              this.setState({ state: this.state }),
          },
        ],
        { cancelable: false }
      );
    }
  };

setRelaxModalVisible(visible) {
  this.setState({relaxModalVisible: visible});

};

setJournalModalVisible(visible) {
  this.setState({journalModalVisible: visible});
};

bendedButton(textObject) {
      return (
        <View>
          <ImageBackground resizeMode="contain" style={[styles.bendedButton, {position: 'absolute'}]} source={BendedButton} >
            {textObject}
          </ImageBackground>
        </View>
      )
}

writeSomething(text) {
  console.log(text);
}

  render() {
    return (
      <View style={styles.container} >


      {/* Rotation View */}
        <Animated.View style={ [styles.animatedContainer, {transform: [
                                              {rotate: this.state.angle + 'deg'},
                                              {perspective: 1000}
                                            ]}]}   {...this._panResponder.panHandlers}>



        <TouchableHighlight onPress={() => this._ScreenChange('OceaimInfo')} style={styles.imageContainer}>
            <Image resizeMode="contain" style={styles.imageButton} source={require('./../assets/OCEAIM_LOGO_SORT.png')} />
        </TouchableHighlight>

        {/* Relax Bended Button */}
            <TouchableOpacity style={[styles.touchableTop, {position: 'relative'}]} onPress={() => this.writeSomething('Relax')}>
              {this.bendedButton(<Text style={styles.buttonTopText}>Slap af</Text>)}
            </TouchableOpacity>

          {/* Support Bended Button */}
            <TouchableOpacity style={styles.touchableLeft} onPress={() => this.writeSomething('Support')}>
              {this.bendedButton(<Text style={styles.buttonLeftText}>Support</Text>)}
            </TouchableOpacity>

          {/* Stress Test Bended Button */}
            <TouchableOpacity style={styles.touchableRight} onPress={() => this.writeSomething('Stress')}>
              {this.bendedButton(<Text style={styles.buttonRightText}>Stress Test</Text>)}
            </TouchableOpacity>

          {/* StressDagbog Bended Button */}
            <TouchableOpacity style={styles.touchableBottom} onPress={() => this.writeSomething('Dagbog')}>
              {this.bendedButton(<Text style={styles.buttonBottomText}>Stressdagbog</Text>)}
            </TouchableOpacity>

            </Animated.View>


            {/* Relax and Meditations Modal */}
              <Modal style={styles.modal} animationType="slide" transparent={true} visible={this.state.relaxModalVisible}>
                <TouchableWithoutFeedback onPress={() => this.setRelaxModalVisible(false)}>
                  <View style={styles.modalView}>
                        <View style={styles.modalButtonContainer}>
                        <TouchableHighlight style={styles.popupButton} onPress={() => this._ScreenChange('Relax')}>
                            <Text style={{fontSize: 13}}>Slap Af</Text>
                        </TouchableHighlight>
                        <TouchableHighlight style={styles.popupButton} onPress={() => this._ScreenChange('Meditation')}>
                            <Text style={{fontSize: 13}}>Meditation</Text>
                        </TouchableHighlight>
                      </View>
                      <View style={{bottom: 60, justifyContent: 'center', alignItems: 'center'}}>
                        <TouchableOpacity
                          onPress={() => {this.setRelaxModalVisible(!this.state.relaxModalVisible);}}
                          style={styles.closeModal} >
                          <Text style={styles.btnText}>LUK</Text>
                        </TouchableOpacity>
                      </View>
                  </View>
                </TouchableWithoutFeedback>
              </Modal>

              {/* Journal Modal */}
              <Modal style={styles.modal} animationType="slide" transparent={true} visible={this.state.journalModalVisible}>
                <TouchableWithoutFeedback onPress={() => this.setJournalModalVisible(false)}>
                  <View style={styles.modalView}>
                        <View style={styles.modalButtonContainer}>
                        <TouchableHighlight style={styles.popupButton} onPress={() => this._ScreenChange('StressTabs')}>
                            <Text style={{fontSize: 13}}>Stressdagbog</Text>
                        </TouchableHighlight>
                        <TouchableHighlight style={styles.popupButton} onPress={() => this._ScreenChange('RessourceTabs')}>
                            <Text style={{fontSize: 13}}>Ressource{"\n"}Dagbog</Text>
                        </TouchableHighlight>
                        <TouchableHighlight style={styles.popupButton} onPress={() => this._ScreenChange('JournalTabs')}>
                            <Text style={{fontSize: 13}}>Journal</Text>
                        </TouchableHighlight>
                      </View>
                      <View style={{bottom: 60, justifyContent: 'center', alignItems: 'center'}}>
                        <TouchableOpacity
                          onPress={() => {this.setJournalModalVisible(!this.state.journalModalVisible);}}
                          style={styles.closeModal} >
                          <Text style={styles.btnText}>LUK</Text>
                        </TouchableOpacity>
                      </View>
                  </View>
                </TouchableWithoutFeedback>
              </Modal>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    backgroundColor: '#4c454a',
    justifyContent: 'center',
    width: FULL_WIDTH,
    height: FULL_HEIGHT
  },
  animatedContainer: {
    width: FULL_WIDTH,
    height: FULL_HEIGHT,
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
  imageContainer:{
    padding: 5,
    height: 210,
    width: 210,
    borderRadius: 210/2,
    position: 'absolute',
  },
  imageButton:{
    height: 210,
    width: 210,
    borderRadius: 210/2,
    borderWidth: 1,
    right: 5,
    bottom: 8,
  },

  bendedButton:{
    width:110,
    height: 220,
  },
  touchableLeft:{
    width:100,
    height: 220,
    right: 122,
    top:110,
    borderRadius: 50,
  },
  touchableRight:{
    width:100,
    height: 220,
    left: 122,
    bottom: 110,
    borderRadius: 50,
    transform: [{rotate: '180deg'}],
  },
  touchableBottom:{
    width:100,
    height: 220,
    bottom: 208,
    borderRadius: 50,
    transform: [{rotate: '270deg'}],
  },
  touchableTop:{
    width:100,
    height: 220,
    top: 208,
    borderRadius: 50,
    transform: [{rotate: '90deg'}],
  },
  buttonRightText: {
    transform: [{rotate: '-90deg'}],
    top: 90,
    right: 10,
    fontWeight: 'bold',
    fontSize: 16
  },
  buttonBottomText:{
    transform: [{rotate: '-90deg'}],
    top: 105,
    right: 9,
    fontWeight: 'bold',
    fontSize: 16
  },
  buttonTopText:{
    transform: [{rotate: '-90deg'}],
    top: 70,
    right: 9,
    fontWeight: 'bold',
    fontSize: 16
  },
  buttonLeftText:{
    transform: [{rotate: '-90deg'}],
    top: 75,
    right: 9,
    fontWeight: 'bold',
    fontSize: 16
  },
  modal:{
    width: 200,
    height: 200,
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: 'rgba(52, 52, 52, 0.8)',
  },
  modalView:{
    flex: 1,
    width: FULL_WIDTH,
    height: FULL_HEIGHT,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: 'rgba(0, 0, 0, 0.4)',
    padding: 10
  },
  modalButtonContainer:{
    bottom: 180,
    flexDirection: 'row',
  },
  popupButton:{
    backgroundColor: '#9ce124',
    width: 100,
    height: 55,
    borderWidth: 1,
    margin: 5,
    alignItems: 'center',
    justifyContent: 'center',
    borderRadius: 15,
    borderWidth: 1,
  },
  closeModal: {
    backgroundColor: '#9ce124',
    width: 150,
    height: 50,
    alignItems: 'center',
    justifyContent: 'center',
    top: 300,
    borderRadius: 15,
    borderWidth: 1,
  },
  btnText:{
    fontSize: 16,
  },
});

HomeScreen.defaultProps = {
  btnRadius: 15,
  dialRadius: 130,
  dialWidth: 5,
  value: 0,
  min: 0,
  max: 359,
  xCenter: Dimensions.get('window').width/2,
  yCenter: Dimensions.get('window').height/2,
  onValueChange: x => x,
}

HomePage выглядит следующим образом: Стандартный угол

после вращения

...