1

I'm using useProgress from react three drei. Apparently, this is used to keep track of the loading state from the models on the scene. I have created a loading screen with a progress bar in which I will be showing the loading state from this progress. But, In all occasions, the progress always goes from 0 to 100 instantly, it does not go from 0...45...50..90.100. Which I believe is wrong, since I have some large models.
This is the base experience component.

import { Dispatch, SetStateAction, Suspense, useRef, useState } from "react";
import OrbitControls from "./components/OrbitControls";
import { Perf } from "r3f-perf";
import { ObjectForReference } from "./components/ObjectForReference";
import * as THREE from "three";
import Room from "./components/Room";
import useLevaControls from "./hook/useLevaControls";
import OverlayLoading from "./components/OverlayLoading";

interface ExperienceProps {
  setHiddenLeva: Dispatch<SetStateAction<boolean>>;
}

export default function Experience({ setHiddenLeva }: ExperienceProps) {
  const invisibleObjectRef = useRef<THREE.Mesh | null>(null);
  const [orbitControlsDisabled, setOrbitControlsDisabled] =
    useState<boolean>(false);
  // Hide overaly
  const [hideOverlay, setHideOverlay] = useState<boolean>(false);
  const [isPointerOnHtml, setIsPointerOnHtml] = useState<boolean>(false);
  const { viewWebpage, showPerformace } = useLevaControls();

  return (
    <>
      <color args={["#2E282A"]} attach="background" />

      {showPerformace && <Perf position="top-left" />}

      <OrbitControls
        invisibleObjectRef={invisibleObjectRef}
        isPointerOnHtml={isPointerOnHtml}
        focusOnHtml={viewWebpage}
        disabled={orbitControlsDisabled}
      />

      <ObjectForReference
        meshRef={invisibleObjectRef}
        position={new THREE.Vector3(-4, 1.7, 0)}
      />

      {!hideOverlay && (
        <OverlayLoading
          setOrbitControlsDisabled={setOrbitControlsDisabled}
          setHiddenLeva={setHiddenLeva}
          setHideOverlay={setHideOverlay}
        />
      )}

      <Suspense>
        <Room
          setIsPointerOnHtml={setIsPointerOnHtml}
          isFocusOnHtml={viewWebpage}
        />
      </Suspense>
    </>
  );
}

As you can see I added some suspense on the Room component so I can render the OveralyLoading first.
This is to render some presentation data:

import "./index.css";
import { useState, useCallback, Dispatch, SetStateAction } from "react";
import { Html } from "@react-three/drei";
import IntroOne from "../IntroScreens/IntroOne";
import IntroTwo from "../IntroScreens/IntroTwo";
import IntroThree from "../IntroScreens/IntroThree";

interface HtmlOverlayProps {
  setOrbitControlsDisabled: Dispatch<SetStateAction<boolean>>;
  setHiddenLeva: Dispatch<SetStateAction<boolean>>;
  setHideOverlay: Dispatch<SetStateAction<boolean>>;
  planeMeshRef: any;
}

export default function HtmlOverlay({
  setHideOverlay,
  setHiddenLeva,
  setOrbitControlsDisabled,
  planeMeshRef,
}: HtmlOverlayProps) {
  const [presentationScreens, setPresentationScreens] = useState(0);

  const handlePresentationScreen = useCallback(() => {
    switch (presentationScreens) {
      case 0:
        return <IntroOne setPresentationScreens={setPresentationScreens} />;
      case 1:
        return <IntroTwo setPresentationScreens={setPresentationScreens} />;
      case 2:
        return (
          <IntroThree
            setHideOverlay={setHideOverlay}
            setHiddenLeva={setHiddenLeva}
            setOrbitControlsDisabled={setOrbitControlsDisabled}
            planeMeshRef={planeMeshRef}
          />
        );
    }
  }, [
    planeMeshRef,
    presentationScreens,
    setHiddenLeva,
    setHideOverlay,
    setOrbitControlsDisabled,
  ]);

  return (
    <Html fullscreen className="htmlComponent">
      {handlePresentationScreen()}
    </Html>
  );
}

The screen inside the Overlay loading, keeps track of the progress:

import { Dispatch, SetStateAction, useEffect } from "react";
import { useProgress } from "@react-three/drei";
import gsap from "gsap";

interface IntroOneProps {
  setPresentationScreens: Dispatch<SetStateAction<number>>;
}

export default function IntroOne({ setPresentationScreens }: IntroOneProps) {
  const { progress } = useProgress();

  useEffect(() => {
    if (progress === 100) {
      setTimeout(() => {
        gsap.to(".opacityControl", {
          opacity: 0,
          onComplete: () => {
            setPresentationScreens(1);
          },
        });
      }, 1500);
    }
  }, [progress, setPresentationScreens]);

  return (
    <div className="localHtml opacityControl">
      <div className="commonHtml">
        <div style={{ marginBottom: 20 }}>
          <span className="introText">We are loading your experience</span>
        </div>

        <div className="progressBar">
          <div
            style={{
              height: "100%",
              borderRadius: 10,
              width: `${progress}%`,
              backgroundColor: "#0061FF",
            }}
          ></div>
        </div>
      </div>
    </div>
  );
}

Nilton Schumacher F
  • 814
  • 3
  • 13
  • 43

0 Answers0