Advertisement
Guest User

Untitled

a guest
Mar 25th, 2019
247
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.48 KB | None | 0 0
  1. import React from 'react';
  2. import { View, StyleSheet, Animated, Dimensions, PanResponder } from 'react-native';
  3.  
  4. const { width } = Dimensions.get('window');
  5.  
  6. export const Route = () => null;
  7.  
  8. const buildSceneConfig = (children = []) => {
  9. const config = {};
  10.  
  11. children.forEach(child => {
  12. config[child.props.name] = { key: child.props.name, component: child.props.component };
  13. });
  14.  
  15. return config;
  16. };
  17.  
  18. export class Navigator extends React.Component {
  19. constructor(props) {
  20. super(props);
  21.  
  22. const sceneConfig = buildSceneConfig(props.children);
  23. const initialSceneName = props.children[0].props.name;
  24.  
  25. this.state = {
  26. sceneConfig,
  27. stack: [sceneConfig[initialSceneName]],
  28. };
  29. }
  30.  
  31. _animatedValue = new Animated.Value(0);
  32.  
  33. _panResponder = PanResponder.create({
  34.  
  35. onMoveShouldSetPanResponder: (evt, gestureState) =>
  36. {
  37. const isFirstScreen = this.state.stack.length === 1
  38. const isFarLeft = evt.nativeEvent.pageX < Math.floor(width * 0.10); // original 0.25
  39.  
  40. if (!isFirstScreen && isFarLeft) {
  41. return true;
  42. }
  43. return false;
  44. },
  45.  
  46. onPanResponderMove: (evt, gestureState) => {
  47. this._animatedValue.setValue(gestureState.moveX);
  48. },
  49.  
  50. onPanResponderTerminationRequest: (evt, gestureState) => true,
  51.  
  52. onPanResponderRelease: (evt, gestureState) => {
  53. if (Math.floor(gestureState.moveX) >= width / 4) {
  54. this.handlePop();
  55. } else {
  56. Animated.timing(this._animatedValue, {
  57. toValue: 0,
  58. duration: 250,
  59. useNativeDriver: true,
  60. }).start();
  61. }
  62. },
  63.  
  64. onPanResponderTerminate: (evt, gestureState) => {
  65. Animated.timing(this._animatedValue, {
  66. toValue: 0, //animate to opacity 0
  67. duration: 250,
  68. useNativeDriver: true,
  69. }).start();
  70. },
  71. });
  72.  
  73. handlePush = (sceneName) => {
  74. this.setState(state => ({
  75. ...state,
  76. stack: [...state.stack, state.sceneConfig[sceneName]],
  77. }), () => {
  78. this._animatedValue.setValue(width);
  79. Animated.timing(this._animatedValue, {
  80. toValue: 0,
  81. duration: 250,
  82. useNativeDriver: true,
  83. }).start();
  84. });
  85. }
  86.  
  87. handlePop = () => {
  88. Animated.timing(this._animatedValue, {
  89. toValue: width,
  90. duration: 250,
  91. useNativeDriver: true,
  92. }).start(() => {
  93. this._animatedValue.setValue(0);
  94. this.setState(state => {
  95. const { stack } = state;
  96. if (stack.length > 1) {
  97. return {
  98. stack: stack.slice(0, stack.length - 1),
  99. };
  100. }
  101.  
  102. return state;
  103. });
  104. });
  105. }
  106.  
  107. render() {
  108. return (
  109. <View style={styles.container} {...this._panResponder.panHandlers}>
  110. {this.state.stack.map((scene, index) => {
  111. const CurrentScene = scene.component;
  112. const sceneStyles = [styles.scene];
  113.  
  114. if (index === this.state.stack.length - 1 && index > 0) {
  115. sceneStyles.push({
  116. transform: [
  117. {
  118. translateX: this._animatedValue,
  119. }
  120. ]
  121. });
  122. }
  123.  
  124. return (
  125. <Animated.View key={scene.key} style={sceneStyles}>
  126. <CurrentScene
  127. navigator={{ push: this.handlePush, pop: this.handlePop }}
  128. />
  129. </Animated.View>
  130. );
  131. })}
  132. </View>
  133. )
  134. }
  135. }
  136.  
  137. const styles = StyleSheet.create({
  138. container: {
  139. flex: 1,
  140. flexDirection: 'row',
  141. },
  142. scene: {
  143. ...StyleSheet.absoluteFillObject,
  144. flex: 1,
  145. },
  146. });
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement