Advertisement
Guest User

Untitled

a guest
Oct 19th, 2017
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.57 KB | None | 0 0
  1. import * as React from 'react';
  2. import {
  3. View,
  4. StyleSheet,
  5. Animated,
  6. Dimensions,
  7. PanResponder,
  8. PanResponderInstance,
  9. Vibration,
  10. Easing
  11. } from 'react-native';
  12. import {observable,computed} from 'mobx';
  13. import {observer} from 'mobx-react'
  14. import ViewModel from './store';
  15. const {width,height} =Dimensions.get('window');
  16.  
  17.  
  18. var flatten = require('flattenStyle');
  19.  
  20. interface JoystickProps
  21. {
  22. beforeResponderMove?(distance:number,angleInRadians:number):void;
  23. onResponderMove?(distance:number,angleInRadians:number):void;
  24. beforeResponderRelease?(oldX:number,oldY:number):void;
  25. onResponderRelease?(distance:number,angleInRadians:number):void;
  26. onResponderReleasing?(x:number,y:number);
  27. onReleaseFinished?();
  28. onInit?(viewModel:ViewModel):void;
  29. }
  30.  
  31. interface JoystickState
  32. {
  33. pan:Animated.ValueXY,
  34. startAnimation:Animated.ValueXY,
  35. mainCircleBackground:string
  36. mainCircleSide:number
  37. mainCircleBorder:number
  38. }
  39.  
  40.  
  41. @observer
  42. export default class Joystick extends React.Component<JoystickProps,JoystickState>
  43. {
  44. private RADIUS = 120;
  45. private PanResponder : PanResponderInstance;
  46. private view : any;
  47. public viewModel : ViewModel;
  48.  
  49. get ViewModel():ViewModel{return this.viewModel;}
  50. get Radius():number {return this.RADIUS;}
  51. constructor(props)
  52. {
  53. super(props);
  54. this.state = {
  55. pan: new Animated.ValueXY({x:0,y:0}),
  56. startAnimation:new Animated.ValueXY({x:0,y:0}),
  57. mainCircleBackground:'#F2F1EF',
  58. mainCircleSide: 1,
  59. mainCircleBorder: 1
  60. }
  61. this.state.startAnimation.addListener(({x,y})=>
  62. {
  63. this.setState({mainCircleBorder : Math.round((width/2) * y),mainCircleSide : Math.round((width - 40) * x)})
  64. });
  65.  
  66. Animated.timing(
  67. this.state.startAnimation,
  68. {toValue:{x:1,y:1}, duration:750, easing:Easing.bounce}
  69. ).start();
  70.  
  71. this.state.pan.addListener(({x,y})=>{
  72. const [newX,newY] = [Math.floor(x),Math.floor(y)];
  73. if(this.props.onResponderReleasing != null)
  74. this.props.onResponderReleasing(newX,newY);
  75. if(newX == 0 && newY == 0 && this.props.onReleaseFinished !=null)
  76. this.props.onReleaseFinished();
  77. })
  78. this.viewModel = new ViewModel(width,height,this.RADIUS);
  79. this.PanResponder = PanResponder.create({
  80. onStartShouldSetPanResponder : this.ViewModel.onStartShouldSetPanResponder,
  81. onPanResponderGrant: (evt, gestureState) => {
  82. Vibration.vibrate([0,250,200],false);
  83. },
  84. onPanResponderMove: (event,gestureEvent) =>
  85. {
  86. if(this.props.beforeResponderMove !=null)
  87. this.props.beforeResponderMove(this.ViewModel.distance,this.ViewModel.angleInRadians);
  88. this.ViewModel.onPanResponderMove(gestureEvent.x0,gestureEvent.y0,gestureEvent.dx,gestureEvent.dy);
  89. if(this.props.onResponderMove !=null)
  90. this.props.onResponderMove(this.ViewModel.distance,this.ViewModel.angleInRadians);
  91. this.state.pan.setValue({x:this.ViewModel.x,y:this.ViewModel.y});
  92. },
  93. onPanResponderRelease: (e, gesture) => {
  94. const [oldX,oldY,distance] = [this.viewModel.x,this.viewModel.y,this.viewModel.distance];
  95. if(this.props.beforeResponderRelease !=null)
  96. this.props.beforeResponderRelease(oldX,oldY);
  97. this.ViewModel.onPanResponderRelease();
  98. if(this.props.onResponderRelease !=null)
  99. this.props.onResponderRelease(this.ViewModel.distance,this.ViewModel.angleInRadians);
  100.  
  101. Animated.timing(
  102. this.state.pan,
  103. {
  104. toValue:{x:0,y:0},
  105. duration:Math.round(distance/200 * 1000),
  106. easing:Easing.bounce
  107. }
  108. ).start();
  109. //
  110. }
  111. })
  112. this.props.onInit(this.viewModel);
  113. }
  114.  
  115. render()
  116. {
  117.  
  118. return(
  119. <View>
  120. <View style={{width:width, height:width, padding:20, justifyContent:'center', alignItems:'center'}}>
  121. <View style={{width:this.state.mainCircleSide, height:this.state.mainCircleSide,borderRadius:this.state.mainCircleBorder,backgroundColor:this.state.mainCircleBackground}}></View>
  122. </View>
  123.  
  124. <View style={{ position : 'absolute', top : (width/2 - CIRCLE_RADIUS), left : (width/2 - CIRCLE_RADIUS)}}>
  125. <Animated.View {...this.PanResponder.panHandlers}
  126. ref={(view)=>this.view = view}
  127. style={[ styles.circle,{left:this.state.pan.x,top:this.state.pan.y},{width: CIRCLE_RADIUS*2,height: CIRCLE_RADIUS*2}]}>
  128. </Animated.View>
  129. </View>
  130. </View>);
  131. }
  132. }
  133.  
  134.  
  135. const CIRCLE_RADIUS = 40;
  136. const styles =StyleSheet.create({
  137. mainContainer: {
  138. flex : 1,
  139. backgroundColor:'#ABB7B7'
  140. },
  141. statusBar : {
  142. flex:1,
  143. height : 200,
  144. backgroundColor:'#ABB7B7',
  145. },
  146. draggableContainer: {
  147. position : 'absolute',
  148. top : (width/2 - CIRCLE_RADIUS),
  149. left : (width/2 - CIRCLE_RADIUS),
  150.  
  151. },
  152. circle : {
  153. backgroundColor : '#1abc9c',
  154. borderRadius : CIRCLE_RADIUS,
  155. position:'absolute',
  156. top:0,
  157. left:0
  158. }
  159. });
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement