Permalink
Newer
100644
200 lines (116 sloc)
4.12 KB
5
const button = document.createElement( 'button' );
6
9
let currentSession = null;
11
async function onSessionStarted( session ) {
12
13
session.addEventListener( 'end', onSessionEnded );
14
15
await renderer.xr.setSession( session );
16
button.textContent = 'EXIT VR';
17
18
currentSession = session;
19
20
}
21
22
function onSessionEnded( /*event*/ ) {
23
24
currentSession.removeEventListener( 'end', onSessionEnded );
25
26
button.textContent = 'ENTER VR';
27
28
currentSession = null;
29
30
}
31
32
//
33
34
button.style.display = '';
35
36
button.style.cursor = 'pointer';
37
button.style.left = 'calc(50% - 50px)';
38
button.style.width = '100px';
39
40
button.textContent = 'ENTER VR';
41
42
button.onmouseenter = function () {
43
44
button.style.opacity = '1.0';
45
46
};
47
48
button.onmouseleave = function () {
49
50
button.style.opacity = '0.5';
51
52
};
53
54
button.onclick = function () {
55
56
if ( currentSession === null ) {
57
58
// WebXR's requestReferenceSpace only works if the corresponding feature
59
// was requested at session creation time. For simplicity, just ask for
60
// the interesting ones as optional features, but be aware that the
61
// requestReferenceSpace call will fail if it turns out to be unavailable.
62
// ('local' is always available for immersive sessions and doesn't need to
63
// be requested separately.)
64
65
const sessionInit = { optionalFeatures: [ 'local-floor', 'bounded-floor', 'hand-tracking', 'layers' ] };
66
navigator.xr.requestSession( 'immersive-vr', sessionInit ).then( onSessionStarted );
67
68
} else {
69
70
currentSession.end();
71
72
}
73
74
};
75
76
}
77
78
function disableButton() {
79
80
button.style.display = '';
81
82
button.style.cursor = 'auto';
83
button.style.left = 'calc(50% - 75px)';
84
button.style.width = '150px';
85
86
button.onmouseenter = null;
87
button.onmouseleave = null;
88
89
button.onclick = null;
90
91
}
92
94
95
disableButton();
96
101
function showVRNotAllowed( exception ) {
102
103
disableButton();
104
105
console.warn( 'Exception when trying to call xr.isSessionSupported', exception );
106
107
button.textContent = 'VR NOT ALLOWED';
108
109
}
110
111
function stylizeElement( element ) {
112
113
element.style.position = 'absolute';
114
element.style.bottom = '20px';
115
element.style.padding = '12px 6px';
116
element.style.border = '1px solid #fff';
117
element.style.borderRadius = '4px';
118
element.style.background = 'rgba(0,0,0,0.1)';
119
element.style.color = '#fff';
120
element.style.font = 'normal 13px sans-serif';
121
element.style.textAlign = 'center';
122
element.style.opacity = '0.5';
123
element.style.outline = 'none';
124
element.style.zIndex = '999';
125
126
}
127
128
if ( 'xr' in navigator ) {
129
131
button.style.display = 'none';
132
133
stylizeElement( button );
134
135
navigator.xr.isSessionSupported( 'immersive-vr' ).then( function ( supported ) {
136
139
if ( supported && VRButton.xrSessionIsGranted ) {
140
141
button.click();
142
143
}
144
145
} ).catch( showVRNotAllowed );
146
147
return button;
148
149
} else {
150
151
const message = document.createElement( 'a' );
155
message.href = document.location.href.replace( /^http:/, 'https:' );
156
message.innerHTML = 'WEBXR NEEDS HTTPS'; // TODO Improve message
157
158
} else {
159
160
message.href = 'https://immersiveweb.dev/';
161
message.innerHTML = 'WEBXR NOT AVAILABLE';
162
163
}
164
165
message.style.left = 'calc(50% - 90px)';
166
message.style.width = '180px';
167
message.style.textDecoration = 'none';
168
169
stylizeElement( message );
170
171
return message;
172
173
}
174
175
}
176
177
static registerSessionGrantedListener() {
178
179
if ( 'xr' in navigator ) {
180
181
// WebXRViewer (based on Firefox) has a bug where addEventListener
182
// throws a silent exception and aborts execution entirely.
183
if ( /WebXRViewer\//i.test( navigator.userAgent ) ) return;
185
navigator.xr.addEventListener( 'sessiongranted', () => {
186
187
VRButton.xrSessionIsGranted = true;
188
189
} );
190
191
}
192
193
}
194
198
VRButton.registerSessionGrantedListener();
199
200
export { VRButton };