Alex's Notes

CM3050 Lab 4504: Conditional Boundaries

import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Animated, PanResponder, View } from 'react-native';
import {useRef, useState} from 'react';

export default function App() {

  const pan = useRef(new Animated.ValueXY()).current;

  const [circleColor, setCircleColor] = useState(-1);

  const panResponder = useRef(
    PanResponder.create({
      onMoveShouldSetPanResponder: (evt, gestureState) => true,
      onPanResponderGrant: (evt, gestureState) => {
	pan.setOffset({
	  x: pan.x._value,
	  y: pan.y._value
	})
      },
      onPanResponderMove: Animated.event(
	  [
	    null,
	    {dx: pan.x, dy: pan.y}
	  ],
	  {useNativeDriver: false}
	)
      ,
      onPanResponderRelease: () => {
	pan.flattenOffset();
	if (pan.y._value < 0) {
	  setCircleColor(0);
	} else {
	  setCircleColor(1);
	}
      }
    })
  ).current;

  let circle_colour_label;
  if (circleColor === -1) {
    circle_colour_label = 'black';
  } else if (circleColor === 0) {
    circle_colour_label = 'green';
  } else {
    circle_colour_label = 'red';
  }

  return (
    <View style={styles.container}>
      <View style={styles.bottomHalf} />
      <View style={styles.topHalf} />
      <Animated.View
	style={{
	  transform: [{translateX: pan.x}, {translateY: pan.y}]
	}}
	{...panResponder.panHandlers}
	>
	<View style={[styles.circle, {backgroundColor: circle_colour_label}]}></View>
      </Animated.View>

      <StatusBar style="auto" />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
  bottomHalf: {
    position: "absolute",
    width: "100%",
    height: "50%",
    bottom: 0,
    backgroundColor: "transparent",
    borderWidth: 10,
    borderColor: "red"
  },
  topHalf: {
    position: "absolute",
    width: "100%",
    height: "50%",
    top: 0,
    backgroundColor: "transparent",
    borderWidth: 10,
    borderColor: "green"
  },
  circle: {
    width: 150,
    height: 150,
    borderRadius: 75,
    backgroundColor: 'blue'
  }
});