expo / expo-three

Utilities for using THREE.js on Expo
MIT License
712 stars 87 forks source link

start rendering loop after fetch all data from api #221

Open hatem-mazid opened 2 years ago

hatem-mazid commented 2 years ago

I try to make a weather app with 3d background so I'm using Axios to get data from weather API the problem is the rendering loop starts before I get API data

App.js:

export default function App() {
  const [liveWeather, setLiveWeather] = useState({});
  const findCoordinates = () => {
    (async () => {
      let { status } = await Location.requestForegroundPermissionsAsync();
      if (status !== "granted") {
        setErrorMsg("Permission to access location was denied");
        return;
      }
      await Location.getCurrentPositionAsync({ enableHighAccuracy: false })
        .then((res) => {
          axios
            .get(
              "http://api.openweathermap.org/data/2.5/weather?lat=${res.coords.latitude}&lon=${res.coords.longitude}&appid=${WEATHER_KEY}&units=metric"
            )
            .then((res) => setLiveWeather(res))
            .catch((err) => console.log(err));
        })
        .catch((er) => console.log(er));
    })();
  };
  useEffect(() => findCoordinates(), []);
  return (
    <View style={styles.container}>
      <Background
        time={moment(liveWeather.headers?.date).unix()}
        sunrise={liveWeather.data?.sys.sunrise}
        sunset={liveWeather.data?.sys.sunset}
      />
      <TouchableOpacity
        onPress={() => {
          findCoordinates();
        }}
        style={{ margin: 30 }}
      >
        <TopHeader
          city={liveWeather.data?.name}
          temp={Math.round(liveWeather.data?.main.temp)}
          date={liveWeather.headers?.date}
        />
        <BottomBar
          pressure={liveWeather.data?.main.pressure}
          humidity={liveWeather.data?.main.humidity}
          wind={liveWeather.data?.wind.speed}
          sunrise={liveWeather.data?.sys.sunrise}
          sunset={liveWeather.data?.sys.sunset}
        />
      </TouchableOpacity>
    </View>
  );
}
const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
    justifyContent: "space-around",
    alignItems: "center",
    width: "100%",
  },
});

background.js:

const Background = (props) => {
  const [sunrise, setSunrise] = useState(null);
  const [sunset, setSunset] = useState(null);
  const [time, setTime] = useState(null);
  const [percent, setPercent] = useState(0);
  let halfScreenWidth = (5 * Math.tan(37.5 * (Math.PI / 180))) / 2;
  useEffect(() => {
    setSunrise(props.sunrise);
    setSunset(props.sunset);
    setTime(props.time);
    setPercent((time - sunrise) / (sunset - sunrise));
    console.log("update::: " + sunrise, sunset, time, percent);
  }, []);
  return (
    <GLView
      style={{
        flex: 1,
        position: "absolute",
        width: "100%",
        height: "100%",
      }}
      onContextCreate={async (gl) => {
        const sceneColor = 0x6ad6f0;
        let width = gl.drawingBufferWidth;
        let height = gl.drawingBufferHeight;
        const renderer = new Renderer({ gl });
        renderer.setSize(width, height);
        renderer.setClearColor(sceneColor);
        const camera = new PerspectiveCamera(75, width / height, 0.01, 1000);
        camera.position.set(0, 0, 5);
        const scene = new Scene();
        scene.add(new GridHelper(10, 10));
        const geo = new SphereGeometry(0.3, 32, 16);
        const mate = new MeshPhongMaterial({ color: 0xffff00 });
        const cube = new Mesh(geo, mate);
        scene.add(cube);
        scene.add(new AmbientLight(0xffffff));
        scene.add(new DirectionalLight(0xffffff, 100));
        const render = () => {
          requestAnimationFrame(render);
          renderer.render(scene, camera);
          gl.endFrameEXP();
         cconsole.log(sunrise, sunset, time, percent);  // the output is undefined 
        };
        render();
      }}
    />
  );
};
export default Background;