Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Added XRButton.js * Examples: Updated relevant examples using XRButton. * WebXRManager: Added setSessionMode(). * WebGLRenderer: Force clear when sessionMode is 'immersive-ar'. * Clean up. * WebXRManager: Force alpha: true in layerInit. * WebGLRenderer: Set state.buffers.color before calling clear() for 'immersive-ar'. * Fix typo * WebGLBackground: Handle WebXR sessions environmentBlendMode. * WebXRManager: Removed setSessionMode(). * XRButton: Revert extra removal.
- Loading branch information
Showing
18 changed files
with
244 additions
and
436 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,198 @@ | ||
class XRButton { | ||
|
||
static createButton( renderer ) { | ||
|
||
const button = document.createElement( 'button' ); | ||
|
||
function showStartXR( mode ) { | ||
|
||
let currentSession = null; | ||
|
||
async function onSessionStarted( session ) { | ||
|
||
session.addEventListener( 'end', onSessionEnded ); | ||
|
||
await renderer.xr.setSession( session ); | ||
|
||
button.textContent = 'STOP XR'; | ||
|
||
currentSession = session; | ||
|
||
} | ||
|
||
function onSessionEnded( /*event*/ ) { | ||
|
||
currentSession.removeEventListener( 'end', onSessionEnded ); | ||
|
||
button.textContent = 'START XR'; | ||
|
||
currentSession = null; | ||
|
||
} | ||
|
||
// | ||
|
||
button.style.display = ''; | ||
|
||
button.style.cursor = 'pointer'; | ||
button.style.left = 'calc(50% - 50px)'; | ||
button.style.width = '100px'; | ||
|
||
button.textContent = 'START XR'; | ||
|
||
button.onmouseenter = function () { | ||
|
||
button.style.opacity = '1.0'; | ||
|
||
}; | ||
|
||
button.onmouseleave = function () { | ||
|
||
button.style.opacity = '0.5'; | ||
|
||
}; | ||
|
||
button.onclick = function () { | ||
|
||
if ( currentSession === null ) { | ||
|
||
const sessionInit = { | ||
optionalFeatures: [ | ||
'local-floor', | ||
'bounded-floor', | ||
'hand-tracking', | ||
'layers' | ||
] | ||
}; | ||
|
||
navigator.xr.requestSession( mode, sessionInit ) | ||
.then( onSessionStarted ); | ||
|
||
} else { | ||
|
||
currentSession.end(); | ||
|
||
} | ||
|
||
}; | ||
|
||
} | ||
|
||
function disableButton() { | ||
|
||
button.style.display = ''; | ||
|
||
button.style.cursor = 'auto'; | ||
button.style.left = 'calc(50% - 75px)'; | ||
button.style.width = '150px'; | ||
|
||
button.onmouseenter = null; | ||
button.onmouseleave = null; | ||
|
||
button.onclick = null; | ||
|
||
} | ||
|
||
function showXRNotSupported() { | ||
|
||
disableButton(); | ||
|
||
button.textContent = 'XR NOT SUPPORTED'; | ||
|
||
} | ||
|
||
function showXRNotAllowed( exception ) { | ||
|
||
disableButton(); | ||
|
||
console.warn( 'Exception when trying to call xr.isSessionSupported', exception ); | ||
|
||
button.textContent = 'XR NOT ALLOWED'; | ||
|
||
} | ||
|
||
function stylizeElement( element ) { | ||
|
||
element.style.position = 'absolute'; | ||
element.style.bottom = '20px'; | ||
element.style.padding = '12px 6px'; | ||
element.style.border = '1px solid #fff'; | ||
element.style.borderRadius = '4px'; | ||
element.style.background = 'rgba(0,0,0,0.1)'; | ||
element.style.color = '#fff'; | ||
element.style.font = 'normal 13px sans-serif'; | ||
element.style.textAlign = 'center'; | ||
element.style.opacity = '0.5'; | ||
element.style.outline = 'none'; | ||
element.style.zIndex = '999'; | ||
|
||
} | ||
|
||
if ( 'xr' in navigator ) { | ||
|
||
button.id = 'XRButton'; | ||
button.style.display = 'none'; | ||
|
||
stylizeElement( button ); | ||
|
||
navigator.xr.isSessionSupported( 'immersive-ar' ) | ||
.then( function ( supported ) { | ||
|
||
if ( supported ) { | ||
|
||
showStartXR( 'immersive-ar' ); | ||
|
||
} else { | ||
|
||
navigator.xr.isSessionSupported( 'immersive-vr' ) | ||
.then( function ( supported ) { | ||
|
||
if ( supported ) { | ||
|
||
showStartXR( 'immersive-vr' ); | ||
|
||
} else { | ||
|
||
showXRNotSupported(); | ||
|
||
} | ||
|
||
} ).catch( showXRNotAllowed ); | ||
|
||
} | ||
|
||
} ).catch( showXRNotAllowed ); | ||
|
||
return button; | ||
|
||
} else { | ||
|
||
const message = document.createElement( 'a' ); | ||
|
||
if ( window.isSecureContext === false ) { | ||
|
||
message.href = document.location.href.replace( /^http:/, 'https:' ); | ||
message.innerHTML = 'WEBXR NEEDS HTTPS'; // TODO Improve message | ||
|
||
} else { | ||
|
||
message.href = 'https://immersiveweb.dev/'; | ||
message.innerHTML = 'WEBXR NOT AVAILABLE'; | ||
|
||
} | ||
|
||
message.style.left = 'calc(50% - 90px)'; | ||
message.style.width = '180px'; | ||
message.style.textDecoration = 'none'; | ||
|
||
stylizeElement( message ); | ||
|
||
return message; | ||
|
||
} | ||
|
||
} | ||
|
||
} | ||
|
||
export { XRButton }; |
Binary file not shown.
Binary file not shown.
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
Oops, something went wrong.