Skip to content

Commit aface1e

Browse files
committed
✨ ensure the canvas is a child of body
1 parent e781da4 commit aface1e

File tree

2 files changed

+67
-65
lines changed

2 files changed

+67
-65
lines changed

index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
left: 0;
2424
/* pointer-events: none; */
2525
}
26-
#canvas-container {
26+
#canvas {
2727
position: fixed;
2828
width: 100%;
2929
height: 100%;
@@ -33,7 +33,7 @@
3333
</style>
3434
</head>
3535
<body>
36-
<div id="canvas-container"></div>
36+
<canvas id="canvas"></canvas>
3737
<div id="overlay"></div>
3838
<script type="module" src="/src/index.tsx"></script>
3939
</body>

src/App/App.tsx

Lines changed: 65 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as React from "react";
22
import * as THREE from "three";
33
import { GithubLogo } from "./Ui/GithubLogo";
4-
import { Canvas } from "@react-three/fiber";
4+
import { Canvas, extend, events, createRoot } from "@react-three/fiber";
55
import { XR8Controls } from "../XR8Canvas/XR8Controls";
66
import { loadXR8, xr8Hosted } from "../XR8Canvas/getXR8";
77
import { Game } from "./Game";
@@ -17,6 +17,7 @@ import { useProgress } from "@react-three/drei";
1717
import { useIsWebXRSupported } from "../WebXRCanvas/useWebXRSession";
1818
import { useDelay } from "./Ui/useDelay";
1919
import { LoadingScreen } from "./Ui/LoadingScreen";
20+
2021
// @ts-ignore
2122
import { Visualizer } from "react-touch-visualizer";
2223

@@ -53,8 +54,6 @@ export const App = () => {
5354
// force the state to be loading in SSR
5455
if (useIsSSR()) state = { type: "loading" };
5556

56-
const uiTunnel = React.useMemo(tunnel, []);
57-
5857
const [error, setError] = React.useState<Error>();
5958
if (error) throw error;
6059

@@ -104,70 +103,76 @@ export const App = () => {
104103

105104
const hint = useDelay(readyForRender && !readyForGame && "tracking", 2500);
106105

106+
const renderer = React.useMemo(() => {
107+
if (typeof document === "undefined") return;
108+
const canvas = document?.getElementById("canvas") as HTMLCanvasElement;
109+
return new THREE.WebGLRenderer({
110+
canvas,
111+
alpha: true,
112+
antialias: true,
113+
powerPreference: "high-performance",
114+
});
115+
}, []);
116+
117+
const uiTunnel = React.useMemo(tunnel, []);
118+
107119
return (
108120
<>
109-
{state.type !== "loading" && (
110-
<CanvasContainerPortal>
111-
<Canvas
112-
camera={{
113-
position: new THREE.Vector3(0, 6, 6),
114-
near: 0.1,
115-
far: 1000,
116-
}}
117-
shadows
118-
style={{
119-
position: "fixed",
120-
top: 0,
121-
left: 0,
122-
right: 0,
123-
bottom: 0,
124-
touchAction: "none",
125-
opacity: readyForRender ? 1 : 0,
126-
}}
127-
>
128-
{state.type === "xr8" && state.xr8 && (
129-
<XR8Controls
130-
xr8={state.xr8}
131-
onPoseFound={() => setState((s) => ({ ...s, poseFound: true }))}
132-
onCameraFeedDisplayed={() =>
133-
setState((s) => ({ ...s, cameraFeedDisplayed: true }))
134-
}
135-
/>
136-
)}
137-
138-
{state.type === "webXR" && state.webXRSession && (
139-
<WebXRControls
140-
worldSize={8}
141-
webXRSession={state.webXRSession}
142-
onPoseFound={() => setState((s) => ({ ...s, poseFound: true }))}
143-
onCameraFeedDisplayed={() =>
144-
setState((s) => ({ ...s, cameraFeedDisplayed: true }))
145-
}
146-
/>
147-
)}
121+
<Canvas
122+
gl={renderer} // the renderer is created before so we can pass a custom canvas, instead of letting three.js create one. That way the canvas is a direct child of body. Which is supposed to be required for 8thWall (?)
123+
camera={{ position: new THREE.Vector3(0, 6, 6) }}
124+
shadows
125+
style={{
126+
position: "fixed",
127+
top: 0,
128+
left: 0,
129+
right: 0,
130+
bottom: 0,
131+
touchAction: "none",
132+
opacity: readyForRender ? 1 : 0,
133+
}}
134+
>
135+
{state.type === "xr8" && state.xr8 && (
136+
<XR8Controls
137+
xr8={state.xr8}
138+
onPoseFound={() => setState((s) => ({ ...s, poseFound: true }))}
139+
onCameraFeedDisplayed={() =>
140+
setState((s) => ({ ...s, cameraFeedDisplayed: true }))
141+
}
142+
/>
143+
)}
144+
145+
{state.type === "webXR" && state.webXRSession && (
146+
<WebXRControls
147+
worldSize={8}
148+
webXRSession={state.webXRSession}
149+
onPoseFound={() => setState((s) => ({ ...s, poseFound: true }))}
150+
onCameraFeedDisplayed={() =>
151+
setState((s) => ({ ...s, cameraFeedDisplayed: true }))
152+
}
153+
/>
154+
)}
148155

149-
<React.Suspense fallback={null}>
150-
<Environment />
156+
<React.Suspense fallback={null}>
157+
<Environment />
151158

152-
{
153-
/* preload the dice model */
154-
!readyForGame && (
155-
<Dice
156-
position={[999, 999, 9999]}
157-
scale={[0.0001, 0.0001, 0.0001]}
158-
/>
159-
)
160-
}
159+
{
160+
/* preload the dice model */
161+
!readyForGame && (
162+
<Dice
163+
position={[999, 999, 9999]}
164+
scale={[0.0001, 0.0001, 0.0001]}
165+
/>
166+
)
167+
}
161168

162-
{readyForGame && <Game UiPortal={uiTunnel.In} />}
163-
</React.Suspense>
169+
{readyForGame && <Game UiPortal={uiTunnel.In} />}
170+
</React.Suspense>
164171

165-
<directionalLight position={[10, 8, 6]} intensity={0} castShadow />
172+
<directionalLight position={[10, 8, 6]} intensity={0} castShadow />
166173

167-
<Ground />
168-
</Canvas>
169-
</CanvasContainerPortal>
170-
)}
174+
<Ground />
175+
</Canvas>
171176

172177
{false && <Visualizer />}
173178

@@ -205,9 +210,6 @@ export const App = () => {
205210
);
206211
};
207212

208-
const CanvasContainerPortal = ({ children }: { children?: any }) =>
209-
createPortal(children, document.getElementById("canvas-container")!);
210-
211213
const Over = ({ children }: { children?: any }) => (
212214
<div
213215
style={{

0 commit comments

Comments
 (0)