I’m working on a 3D globe visualization using React Three Fiber and the three-globe library. The globe takes 1-3 seconds to load. I’ve added a loading component using the useProgress
hook from @react-three/drei
, but the loader is not displaying as expected. It seems the Suspense fallback is not working properly (the loader element is not showing anything for 2 seconds).
Problem Description
I want the loader to show the loading progress while the 3D globe is being prepared. Ideally, the loader screen should cover the entire page until the 3D globe is fully loaded. However, the loader does not display during the loading period
Here’s my full code Globe.tsx
Code
Here is the relevant code:
export function World(props: WorldProps) {
const { globeConfig } = props;
const scene = new Scene();
scene.fog = new Fog(0xffffff, 400, 2000);
function Loader() {
const { progress } = useProgress();
console.log(progress);
return <h1 className="text-5xl">{progress.toFixed(2)} % loaded</h1>;
}
return (
<Canvas scene={scene} camera={new PerspectiveCamera(60, aspect, 180, 1800)}>
<Suspense fallback={<Loader />}>
<WebGLRendererConfig />
<ambientLight color={globeConfig.ambientLight} intensity={1.0} />
<directionalLight
color={globeConfig.directionalLeftLight}
position={new Vector3(-400, 100, 400)}
intensity={0.8}
/>
<directionalLight
color={globeConfig.directionalTopLight}
position={new Vector3(-200, 500, 200)}
intensity={0.8}
/>
<pointLight
color={globeConfig.pointLight}
position={new Vector3(-200, 500, 200)}
intensity={1.0}
/>
<Globe {...props} />
<OrbitControls
enablePan={false}
enableZoom={false}
minDistance={cameraZ}
maxDistance={cameraZ}
autoRotateSpeed={1}
autoRotate={true}
minPolarAngle={Math.PI / 3.5}
maxPolarAngle={Math.PI - Math.PI / 3}
/>
</Suspense>
</Canvas>
);
}
and I imported the globe.tsx
in a file called section1.tsx
export default function Section1() {
return (
<section className="container mx-auto h-auto lg:h-screen flex flex-col lg:flex-row items-center justify-center gap-4">
<div className="flex-1 p-6 rounded-lg ">
{/* some html.... */}
</div>
<div className="h-[80vh] lg:h-full w-full md:flex lg:w-6/12 p-6 rounded-lg ">
<World data={sampleArcs} globeConfig={globeConfig} />
</div>
</section>
);
}
Rendered HTML
before the globe loaded
<div class="h-[80vh] lg:h-full w-full md:flex lg:w-6/12 p-6 rounded-lg "></div>
Next JS version:14.2.3
Sundar is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.