feat(intro): polish loading transition

This commit is contained in:
Tom Boullay
2026-05-30 20:11:40 +02:00
parent 0fa7a82175
commit e6bfcbe960
9 changed files with 195 additions and 63 deletions
+21 -2
View File
@@ -6,12 +6,14 @@ import { DebugPerf } from "@/components/debug/DebugPerf";
import { DialogMessage } from "@/components/ui/DialogMessage";
import { GameUI } from "@/components/ui/GameUI";
import {
FadeToVideoOverlay,
IntroDialogueOverlay,
IntroRevealOverlay,
IntroVideoPlayer,
} from "@/components/ui/intro";
import { SceneLoadingOverlay } from "@/components/ui/SceneLoadingOverlay";
import { INITIAL_SCENE_LOADING_STATE } from "@/data/world/sceneLoadingConfig";
import { AudioManager } from "@/managers/AudioManager";
import { useGameStore } from "@/managers/stores/useGameStore";
import { HandTrackingProvider } from "@/providers/gameplay/HandTrackingProvider";
import type { SceneLoadingState } from "@/types/world/sceneLoading";
@@ -19,6 +21,8 @@ import { hasSiteBeenVisitedToday } from "@/utils/cookies/siteVisitCookie";
import { logger } from "@/utils/core/Logger";
import { World } from "@/world/World";
const LOADING_TO_VIDEO_FADE_MS = 500;
export function HomePage(): React.JSX.Element | null {
const navigate = useNavigate();
const introStep = useGameStore((state) => state.intro.currentStep);
@@ -67,10 +71,23 @@ export function HomePage(): React.JSX.Element | null {
useEffect(() => {
if (introStep === "loading-map" && sceneLoadingState.status === "ready") {
setIntroStep("video");
AudioManager.getInstance().stopMusic();
setIntroStep("fade-to-video");
}
}, [introStep, sceneLoadingState.status, setIntroStep]);
useEffect(() => {
if (introStep !== "fade-to-video") return undefined;
const timeoutId = window.setTimeout(() => {
setIntroStep("video");
}, LOADING_TO_VIDEO_FADE_MS);
return () => {
window.clearTimeout(timeoutId);
};
}, [introStep, setIntroStep]);
const handleCanvasCreated = useCallback(
({ gl }: { gl: THREE.WebGLRenderer }) => {
const canvas = gl.domElement;
@@ -106,6 +123,8 @@ export function HomePage(): React.JSX.Element | null {
const renderIntroOverlay = () => {
switch (introStep) {
case "fade-to-video":
return <FadeToVideoOverlay />;
case "video":
return <IntroVideoPlayer />;
case "dialogue-intro":
@@ -142,7 +161,7 @@ export function HomePage(): React.JSX.Element | null {
onClose={hideDialog}
/>
) : null}
{introStep === "loading-map" && (
{(introStep === "loading-map" || introStep === "fade-to-video") && (
<SceneLoadingOverlay state={sceneLoadingState} />
)}
{renderIntroOverlay()}