Skip to content

Commit d45ee46

Browse files
Merge pull request #702 from MichaelHazani/add-webxr-template
Add webxr template
2 parents 85776bc + bdac81a commit d45ee46

File tree

11 files changed

+55459
-0
lines changed

11 files changed

+55459
-0
lines changed

templates/html-three-webxr-template/GLTFLoader.js

Lines changed: 4001 additions & 0 deletions
Large diffs are not rendered by default.

templates/html-three-webxr-template/OrbitControls.js

Lines changed: 1072 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# HTML Three.js WebXR Template
2+
3+
This template is very similar to the ThreeJS template, with the minimal modifications to enable a ThreeJS-powered VR scene.
4+
5+
To learn more about how to create immersive WebXR content with ThreeJS, see [How To Create VR Content](https://threejs.org/docs/#manual/en/introduction/How-to-create-VR-content)
6+
7+
All HTML content needs to be minted in a zip file. You can have multiple files inside your zip, however there are a few requirements you can't miss.
8+
9+
1. The HTML file can only be called index.html
10+
2. The file should have a thumbnail image to be displayed until the user clicks to interact on your NFT. The image can be png, jpg or a gif. you just need to update the <metadata> reference inside the HTML file.
11+
3. At the moment calls to external sites are being blocked, even if they seem to work locally when you are testing. So any dependency needs to be included locally in the zip.
12+
13+
Regardless of what content you want to display (three.js, pixi.js, canvas, p5.js, shaders etc), it should always be full width and full height (window.innerWidth and window.innerHeight) so please dont forget to include your own resize function.
14+
15+
Hope you guys enjoy!
16+
Hicetnunc team
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
class VRButton {
2+
3+
static createButton( renderer, options ) {
4+
5+
if ( options ) {
6+
7+
console.error( 'THREE.VRButton: The "options" parameter has been removed. Please set the reference space type via renderer.xr.setReferenceSpaceType() instead.' );
8+
9+
}
10+
11+
const button = document.createElement( 'button' );
12+
13+
function showEnterVR( /*device*/ ) {
14+
15+
let currentSession = null;
16+
17+
async function onSessionStarted( session ) {
18+
19+
session.addEventListener( 'end', onSessionEnded );
20+
21+
await renderer.xr.setSession( session );
22+
button.textContent = 'EXIT VR';
23+
24+
currentSession = session;
25+
26+
}
27+
28+
function onSessionEnded( /*event*/ ) {
29+
30+
currentSession.removeEventListener( 'end', onSessionEnded );
31+
32+
button.textContent = 'ENTER VR';
33+
34+
currentSession = null;
35+
36+
}
37+
38+
//
39+
40+
button.style.display = '';
41+
42+
button.style.cursor = 'pointer';
43+
button.style.left = 'calc(50% - 50px)';
44+
button.style.width = '100px';
45+
46+
button.textContent = 'ENTER VR';
47+
48+
button.onmouseenter = function () {
49+
50+
button.style.opacity = '1.0';
51+
52+
};
53+
54+
button.onmouseleave = function () {
55+
56+
button.style.opacity = '0.5';
57+
58+
};
59+
60+
button.onclick = function () {
61+
62+
if ( currentSession === null ) {
63+
64+
// WebXR's requestReferenceSpace only works if the corresponding feature
65+
// was requested at session creation time. For simplicity, just ask for
66+
// the interesting ones as optional features, but be aware that the
67+
// requestReferenceSpace call will fail if it turns out to be unavailable.
68+
// ('local' is always available for immersive sessions and doesn't need to
69+
// be requested separately.)
70+
71+
const sessionInit = { optionalFeatures: [ 'local-floor', 'bounded-floor', 'hand-tracking' ] };
72+
navigator.xr.requestSession( 'immersive-vr', sessionInit ).then( onSessionStarted );
73+
74+
} else {
75+
76+
currentSession.end();
77+
78+
}
79+
80+
};
81+
82+
}
83+
84+
function disableButton() {
85+
86+
button.style.display = '';
87+
88+
button.style.cursor = 'auto';
89+
button.style.left = 'calc(50% - 75px)';
90+
button.style.width = '150px';
91+
92+
button.onmouseenter = null;
93+
button.onmouseleave = null;
94+
95+
button.onclick = null;
96+
97+
}
98+
99+
function showWebXRNotFound() {
100+
101+
disableButton();
102+
103+
button.textContent = 'VR NOT SUPPORTED';
104+
105+
}
106+
107+
function stylizeElement( element ) {
108+
109+
element.style.position = 'absolute';
110+
element.style.bottom = '20px';
111+
element.style.padding = '12px 6px';
112+
element.style.border = '1px solid #fff';
113+
element.style.borderRadius = '4px';
114+
element.style.background = 'rgba(0,0,0,0.1)';
115+
element.style.color = '#fff';
116+
element.style.font = 'normal 13px sans-serif';
117+
element.style.textAlign = 'center';
118+
element.style.opacity = '0.5';
119+
element.style.outline = 'none';
120+
element.style.zIndex = '999';
121+
122+
}
123+
124+
if ( 'xr' in navigator ) {
125+
126+
button.id = 'VRButton';
127+
button.style.display = 'none';
128+
129+
stylizeElement( button );
130+
131+
navigator.xr.isSessionSupported( 'immersive-vr' ).then( function ( supported ) {
132+
133+
supported ? showEnterVR() : showWebXRNotFound();
134+
135+
} );
136+
137+
return button;
138+
139+
} else {
140+
141+
const message = document.createElement( 'a' );
142+
143+
if ( window.isSecureContext === false ) {
144+
145+
message.href = document.location.href.replace( /^http:/, 'https:' );
146+
message.innerHTML = 'WEBXR NEEDS HTTPS'; // TODO Improve message
147+
148+
} else {
149+
150+
message.href = 'https://immersiveweb.dev/';
151+
message.innerHTML = 'WEBXR NOT AVAILABLE';
152+
153+
}
154+
155+
message.style.left = 'calc(50% - 90px)';
156+
message.style.width = '180px';
157+
message.style.textDecoration = 'none';
158+
159+
stylizeElement( message );
160+
161+
return message;
162+
163+
}
164+
165+
}
166+
167+
}
168+
169+
export { VRButton };

0 commit comments

Comments
 (0)