Skip to content

Commit 9058440

Browse files
committed
Improve loader
1 parent 7699ad1 commit 9058440

File tree

4 files changed

+57
-12
lines changed

4 files changed

+57
-12
lines changed

src/frontend/components/app.tsx

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import {
1212
IRunningGameInstance,
1313
LocalGameInstance,
1414
} from "../../logic/gameinstance";
15-
import { LoadingPage } from "./loading-page";
1615

1716
interface LoadGameProps {
1817
scenario: string;
@@ -88,9 +87,7 @@ export function App() {
8887
);
8988

9089
let root = null;
91-
if (!assetsLoaded) {
92-
root = null;
93-
} else if (gameState) {
90+
if (gameState) {
9491
root = (
9592
<IngameView
9693
scenario={gameState.scenario}
@@ -112,7 +109,6 @@ export function App() {
112109

113110
return (
114111
<MotionConfig reducedMotion={settings.reduceMotion ? "always" : "user"}>
115-
<LoadingPage visible={!assetsLoaded} progress={assetProgress} />
116112
{root}
117113
</MotionConfig>
118114
);

src/frontend/components/atoms/loading.tsx

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1-
import { useEffect, useRef } from "preact/hooks";
1+
import { useEffect, useRef, useState } from "preact/hooks";
22
import video from "../../../assets/ui/loading.webm";
33

4+
const staticVideo = fetch(video, { priority: "high" }).then((v) => v.blob()).then((v) => URL.createObjectURL(v)).finally(() => {
5+
console.log("Video load done");
6+
});
7+
48
const VIDEO_TIME_S = 3;
59

610
export function Loading({
@@ -13,13 +17,21 @@ export function Loading({
1317
loadingDone: () => void;
1418
}) {
1519
const videoRef = useRef<HTMLVideoElement | null>(null);
20+
const [videoSrc, setVideoSrc] = useState<string>();
21+
useEffect(() => {
22+
staticVideo.then((src) => setVideoSrc(src));
23+
}, []);
1624

1725
useEffect(() => {
1826
if (!videoRef.current) {
1927
return;
2028
}
2129
videoRef.current.addEventListener("ended", () => {
22-
loadingDone();
30+
console.log("Loading ended");
31+
if (videoRef.current?.currentTime === VIDEO_TIME_S) {
32+
console.log("Loading Done");
33+
loadingDone();
34+
}
2335
});
2436
}, [videoRef]);
2537

@@ -28,17 +40,20 @@ export function Loading({
2840
return;
2941
}
3042
if (progress === undefined) {
43+
console.log("No progress, playing at full rate");
3144
videoRef.current.playbackRate = 2;
3245
videoRef.current.play();
3346
return;
3447
}
3548
const expectedProgress = VIDEO_TIME_S * progress;
3649
const currentTime = videoRef.current.currentTime;
3750
if (expectedProgress > currentTime) {
51+
console.log("Progress behind", currentTime, expectedProgress);
3852
videoRef.current.playbackRate =
3953
expectedProgress - currentTime > 2 ? 3 : 1;
4054
videoRef.current.play();
4155
} else if (currentTime >= expectedProgress) {
56+
console.log("Progress ahead of current time, pausing", currentTime, expectedProgress);
4257
videoRef.current.pause();
4358
}
4459
}, [videoRef, progress]);
@@ -50,7 +65,7 @@ export function Loading({
5065
style={{ maxWidth: "500px", width: "15vw" }}
5166
className={className}
5267
ref={videoRef}
53-
src={video}
68+
src={videoSrc}
5469
controls={false}
5570
preload="auto"
5671
/>

src/frontend/components/preloader.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { assetLoadPercentage, assetsAreReady } from "../../assets";
2+
import { useObservableEagerState } from "observable-hooks";
3+
import { useGameSettingsHook } from "../../settings";
4+
import { MotionConfig } from "framer-motion";
5+
import { LoadingPage } from "./loading-page";
6+
7+
export function Preloader() {
8+
const assetProgress = useObservableEagerState(assetLoadPercentage);
9+
const assetsLoaded = useObservableEagerState(assetsAreReady);
10+
const [settings] = useGameSettingsHook();
11+
12+
return (
13+
<MotionConfig reducedMotion={settings.reduceMotion ? "always" : "user"}>
14+
<LoadingPage visible={!assetsLoaded} progress={assetProgress} />
15+
</MotionConfig>
16+
);
17+
}

src/main.tsx

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,26 @@
1+
// Ensure we load the video early.
2+
import "./frontend/components/atoms/loading";
13
import { render } from "preact";
24
import "./index.css";
3-
import { App } from "./frontend/components/app";
45
import { loadAssets } from "./assets";
5-
import "core-js/actual/typed-array/from-base64";
6+
import { useEffect, useState } from "preact/hooks";
7+
import { Preloader } from "./frontend/components/preloader";
8+
import type { App as AppType } from "./frontend/components/app";
69

7-
void loadAssets();
810

9-
render(<App />, document.getElementById("app") as HTMLElement);
11+
12+
function Main() {
13+
const [AppImport, setApp] = useState<{ App: typeof AppType }>();
14+
useEffect(() => {
15+
void loadAssets();
16+
// TODO: Error state.
17+
import("./frontend/components/app").then((_app) => setApp(_app));
18+
}, []);
19+
20+
return <>
21+
<Preloader />
22+
{AppImport ? <AppImport.App /> : null}
23+
</>;
24+
}
25+
26+
render(<Main />, document.getElementById("app") as HTMLElement);

0 commit comments

Comments
 (0)