MCPcopy Create free account
hub / github.com/melonjs/melonJS / createExampleComponent

Function createExampleComponent

packages/examples/src/examples/utils.tsx:30–83  ·  view source on GitHub ↗
(
	createGameFn: () => void | (() => void),
)

Source from the content-addressed store, hash-verified

28 * automatically; teardown is for example-owned side-effects only.
29 */
30export const createExampleComponent = (
31 createGameFn: () => void | (() => void),
32) => {
33 return () => {
34 useEffect(() => {
35 if (currentInitFn === createGameFn) {
36 // Same example remounting — engine still alive from the
37 // first mount; the cleanup below detached the canvas, so
38 // re-parent it back into `#screen`.
39 const canvas = game.renderer?.getCanvas();
40 const screen = document.getElementById("screen");
41 if (canvas && screen && !screen.contains(canvas)) {
42 screen.appendChild(canvas);
43 }
44 } else if (currentInitFn !== null) {
45 // Cross-example navigation (e.g. `/lineOfSight` → `/plinko`).
46 // The previous example's engine is still alive but is
47 // running the wrong scene; safest reset is a full page
48 // reload so the new example boots from a clean state.
49 // `game.destroy()` would be cheaper, but it has known
50 // issues under React StrictMode's dev double-mount
51 // (`World.reset` throws after partial teardown). The
52 // reload re-runs `createExampleComponent` from scratch
53 // with `currentInitFn === null`, taking the init branch.
54 globalThis.location.reload();
55 return;
56 } else {
57 // First mount of any example on this page load.
58 currentInitFn = createGameFn;
59 const teardown = createGameFn();
60 currentTeardown = typeof teardown === "function" ? teardown : null;
61 }
62 // Detach the canvas on unmount so a navigation back to the
63 // index page (via the "← Examples" topbar link, same tab)
64 // doesn't leave the engine canvas parented in `#screen`.
65 // `#screen` is `position: fixed` and covers the whole window
66 // beneath the 41 px topbar, so any leftover canvas sits on
67 // top of the index-page link cards and silently eats every
68 // click. Also run the per-example teardown for any DOM /
69 // listener state the example added outside the engine.
70 return () => {
71 const canvas = game.renderer?.getCanvas();
72 if (canvas?.parentElement) {
73 canvas.parentElement.removeChild(canvas);
74 }
75 if (currentTeardown) {
76 currentTeardown();
77 currentTeardown = null;
78 }
79 };
80 }, []);
81 return null;
82 };
83};

Calls 3

getCanvasMethod · 0.80
removeChildMethod · 0.80
containsMethod · 0.45

Tested by

no test coverage detected