I am new to react native. I am trying to build a functionality that needs a View (a circle) randomly moving on the screen. Can someone help me where to start with? Thanks in advance.
update: I am now trying to create a draggable component, which should be dragged along the moving circle and while our dragging component is inside the moving circle, there should be a stopwatch which is running and when we remove hand or the draggable component is outside the moving circle the timer should be reset and start from first. I have created the dragging component and the stop watch, but am not able to get the logic of how to combine these.
import React, {Component} from 'react'
import { View, Dimensions,TouchableHighlight,Text, StyleSheet, PanResponder, Animated} from 'react-native'
import { Stopwatch } from 'react-native-stopwatch-timer'
let {width:W,height:H} = Dimensions.get("window");
class Draggable extends Component {
constructor(props) {
super(props);
this.state = {
showDraggable: true,
pan: new Animated.ValueXY(),
opacity: new Animated.Value(1)
};
}
componentWillMount() {
this._val = { x:0, y:0 }
this.state.pan.addListener((value) => this._val = value);
this.panResponder = PanResponder.create({
onStartShouldSetPanResponder: (e, gesture) => true,
onPanResponderGrant: (e, gesture) => {
this.state.pan.setOffset({
x: this._val.x,
y:this._val.y
})
//console.log(this.state.pan);
this.state.pan.setValue({ x:0, y:0})
},
onPanResponderMove: Animated.event([
null, { dx: this.state.pan.x, dy: this.state.pan.y }
]),
onPanResponderRelease: (e, gesture) => {
this.state.pan.setOffset({x: this._val.x, y: this._val.y});
}
});
}
render() {
return (
<View>
{this.renderDraggable()}
</View>
);
}
renderDraggable() {
const panStyle = {
transform: this.state.pan.getTranslateTransform()
}
if (this.state.showDraggable) {
return (
<Animated.View
{...this.panResponder.panHandlers}
style={[panStyle, styles.circle, styles.dragstyle,{opacity:this.state.opacity}]}
/>
);
}
}
}
class MovingCircle extends React.Component{
constructor(props){
super(props);
this.state={
pos:new Animated.ValueXY
}
}
_loopAnimation(){
let des = {x:W*Math.random(), y:Math.random()*H};
//console.log(this.state.des)
Animated.timing(this.state.pos, {
toValue:des,
duration:4000
}).start(()=>{
this._loopAnimation();
});
}
componentDidMount(){
this._loopAnimation();
}
render(){
return <Animated.View style={{
width:60,height:60,
borderRadius:30,
backgroundColor:"#0A8648",
position:"absolute",
left:this.state.pos.x,
top:this.state.pos.y
}}/>
}
}
export default class App extends React.Component {
constructor (props) {
super(props);
this.state = {
stopwatchStart: false,
stopwatchReset: false,
};
this.toggleStopwatch = this.toggleStopwatch.bind(this);
this.resetStopwatch = this.resetStopwatch.bind(this);
}
toggleStopwatch() {
this.setState({stopwatchStart: !this.state.stopwatchStart, stopwatchReset: false});
}
resetStopwatch() {
this.setState({stopwatchStart: false, stopwatchReset: true});
}
getFormattedTime(time) {
this.currentTime = time;
}
render() {
return (
<View style={styles.mainContainer} >
<MovingCircle />
<View style={styles.dragContainer}>
<Draggable />
</View>
<View style={styles.stopWatchHeader} >
<Stopwatch laps msecs start={this.state.stopwatchStart}
reset={this.state.stopwatchReset}
getTime={this.getFormattedTime} />
<View style={styles.startResetHeader} >
<TouchableHighlight onPress={this.toggleStopwatch}>
<Text style={{fontSize: 20}}>{!this.state.stopwatchStart ? "Start" : "Stop"}</Text>
</TouchableHighlight>
<TouchableHighlight onPress={this.resetStopwatch}>
<Text style={{fontSize: 20}}>Reset</Text>
</TouchableHighlight>
</View>
</View>
</View>
);
}
}
let CIRCLE_RADIUS = 25;
const styles = StyleSheet.create({
mainContainer: {
flex: 1,
backgroundColor:"#D7B68A"
},
circle: {
backgroundColor: "#38395E",
width: CIRCLE_RADIUS * 2,
height: CIRCLE_RADIUS * 2,
borderRadius: CIRCLE_RADIUS
},
dragContainer: {
flex: 1,
flexDirection: "row",
height:150,
justifyContent: "flex-start",
alignItems: "flex-end"
},
stopWatchHeader:{
flexDirection:"row",
backgroundColor:"#FFDEAD",
alignItems:"center",
justifyContent:"space-between",
height:66,
padding:8,
borderRadius:4
},
startResetHeader:{
flex:1,
flexDirection:"row",
justifyContent:"space-around"
}
})
below is a sample, adjust the animation duration and view size by yourself. have a look at the official document of Animations
import React, {Component} from 'react'
import { View,
Dimensions,
StyleSheet, Animated} from 'react-native'
let {width:W,height:H} = Dimensions.get("window");
export default class test0123 extends React.Component{
constructor(props){
super(props);
this.state={
pos:new Animated.ValueXY
}
}
_loopAnimation(){
let des = {x:W*Math.random(), y:Math.random()*H};
Animated.timing(this.state.pos, {
toValue:des,
duration:3000
}).start(()=>{
this._loopAnimation();
});
}
componentDidMount(){
this._loopAnimation();
}
render(){
return <Animated.View style={{
width:50,height:50,
borderRadius:25,
backgroundColor:"red",
position:"absolute",
left:this.state.pos.x,
top:this.state.pos.y
}}/>
}
}