WebVR.js 5.0 KB
Newer Older
M
Mr.doob 已提交
1 2
/**
 * @author mrdoob / http://mrdoob.com
M
Mugen87 已提交
3 4
 * @author Mugen87 / https://github.com/Mugen87
 *
M
Mr.doob 已提交
5 6 7 8 9
 * Based on @tojiro's vr-samples-utils.js
 */

var WEBVR = {

10
	createButton: function ( renderer, options ) {
M
Mugen87 已提交
11

M
Mr.doob 已提交
12 13 14
		if ( options === undefined ) options = {};
		if ( options.frameOfReferenceType === undefined ) options.frameOfReferenceType = 'stage';

M
Mr.doob 已提交
15
		function showEnterVR( device ) {
M
Mugen87 已提交
16

M
Mr.doob 已提交
17 18
			button.style.display = '';

M
Mr.doob 已提交
19 20 21
			button.style.cursor = 'pointer';
			button.style.left = 'calc(50% - 50px)';
			button.style.width = '100px';
M
Mugen87 已提交
22

M
Mr.doob 已提交
23
			button.textContent = 'ENTER VR';
M
Mugen87 已提交
24

M
Mr.doob 已提交
25 26 27
			button.onmouseenter = function () { button.style.opacity = '1.0'; };
			button.onmouseleave = function () { button.style.opacity = '0.5'; };

28 29
			button.onclick = function () {

M
Mr.doob 已提交
30
				device.isPresenting ? device.exitPresent() : device.requestPresent( [ { source: renderer.domElement } ] );
M
Mr.doob 已提交
31

M
Mr.doob 已提交
32 33
			};

M
Mr.doob 已提交
34
			renderer.vr.setDevice( device, options );
M
Mr.doob 已提交
35 36 37 38 39 40 41 42 43 44 45

		}

		function showEnterXR( device ) {

			var currentSession = null;

			function onSessionStarted( session ) {

				session.addEventListener( 'end', onSessionEnded );

46
				renderer.vr.setSession( session, options );
M
Mr.doob 已提交
47
				button.textContent = 'EXIT VR';
M
Mr.doob 已提交
48 49 50 51 52 53

				currentSession = session;

			}

			function onSessionEnded( event ) {
M
Mr.doob 已提交
54

M
Mr.doob 已提交
55 56
				currentSession.removeEventListener( 'end', onSessionEnded );

M
Mr.doob 已提交
57
				renderer.vr.setSession( null );
M
Mr.doob 已提交
58
				button.textContent = 'ENTER VR';
M
Mr.doob 已提交
59

M
Mr.doob 已提交
60
				currentSession = null;
M
Mr.doob 已提交
61

M
Mr.doob 已提交
62 63 64 65 66 67 68 69 70 71
			}

			//

			button.style.display = '';

			button.style.cursor = 'pointer';
			button.style.left = 'calc(50% - 50px)';
			button.style.width = '100px';

M
Mr.doob 已提交
72
			button.textContent = 'ENTER VR';
M
Mr.doob 已提交
73 74 75 76 77

			button.onmouseenter = function () { button.style.opacity = '1.0'; };
			button.onmouseleave = function () { button.style.opacity = '0.5'; };

			button.onclick = function () {
M
Mr.doob 已提交
78

M
Mr.doob 已提交
79
				if ( currentSession === null ) {
M
Mr.doob 已提交
80

81
					device.requestSession( { immersive: true, exclusive: true /* DEPRECATED */ } ).then( onSessionStarted );
M
Mr.doob 已提交
82 83 84

				} else {

M
Mr.doob 已提交
85
					currentSession.end();
M
Mr.doob 已提交
86 87

				}
88 89 90

			};

M
Mr.doob 已提交
91
			renderer.vr.setDevice( device );
92

M
Mr.doob 已提交
93
		}
M
Mugen87 已提交
94

M
Mr.doob 已提交
95
		function showVRNotFound() {
M
Mugen87 已提交
96

M
Mr.doob 已提交
97 98
			button.style.display = '';

M
Mr.doob 已提交
99 100 101
			button.style.cursor = 'auto';
			button.style.left = 'calc(50% - 75px)';
			button.style.width = '150px';
M
Mugen87 已提交
102

M
Mr.doob 已提交
103
			button.textContent = 'VR NOT FOUND';
104

M
Mr.doob 已提交
105 106 107
			button.onmouseenter = null;
			button.onmouseleave = null;

108 109 110 111
			button.onclick = null;

			renderer.vr.setDevice( null );

M
Mr.doob 已提交
112 113 114 115 116 117 118 119 120
		}

		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';
M
Mr.doob 已提交
121
			element.style.background = 'rgba(0,0,0,0.1)';
M
Mr.doob 已提交
122 123 124 125
			element.style.color = '#fff';
			element.style.font = 'normal 13px sans-serif';
			element.style.textAlign = 'center';
			element.style.opacity = '0.5';
M
Mr.doob 已提交
126
			element.style.outline = 'none';
M
Mr.doob 已提交
127 128
			element.style.zIndex = '999';

M
Mr.doob 已提交
129
		}
M
Mugen87 已提交
130

M
Mr.doob 已提交
131 132 133 134 135 136 137 138 139
		if ( 'xr' in navigator ) {

			var button = document.createElement( 'button' );
			button.style.display = 'none';

			stylizeElement( button );

			navigator.xr.requestDevice().then( function ( device ) {

140
				device.supportsSession( { immersive: true, exclusive: true /* DEPRECATED */ } )
141 142
					.then( function () { showEnterXR( device ); } )
					.catch( showVRNotFound );
M
Mr.doob 已提交
143 144 145 146 147 148

			} ).catch( showVRNotFound );

			return button;

		} else if ( 'getVRDisplays' in navigator ) {
M
Mugen87 已提交
149

M
Mr.doob 已提交
150
			var button = document.createElement( 'button' );
M
Mr.doob 已提交
151
			button.style.display = 'none';
M
Mr.doob 已提交
152 153

			stylizeElement( button );
M
Mugen87 已提交
154

M
Mr.doob 已提交
155
			window.addEventListener( 'vrdisplayconnect', function ( event ) {
M
Mr.doob 已提交
156

157
				showEnterVR( event.display );
M
Mugen87 已提交
158

M
Mr.doob 已提交
159
			}, false );
M
Mugen87 已提交
160

M
Mr.doob 已提交
161
			window.addEventListener( 'vrdisplaydisconnect', function ( event ) {
162

M
Mr.doob 已提交
163
				showVRNotFound();
164

M
Mr.doob 已提交
165
			}, false );
M
Mr.doob 已提交
166

M
Mr.doob 已提交
167
			window.addEventListener( 'vrdisplaypresentchange', function ( event ) {
M
Mr.doob 已提交
168

169
				button.textContent = event.display.isPresenting ? 'EXIT VR' : 'ENTER VR';
170 171 172

			}, false );

173 174 175 176 177 178
			window.addEventListener( 'vrdisplayactivate', function ( event ) {

				event.display.requestPresent( [ { source: renderer.domElement } ] );

			}, false );

179 180 181
			navigator.getVRDisplays()
				.then( function ( displays ) {

M
Mr.doob 已提交
182 183 184 185 186 187 188 189 190
					if ( displays.length > 0 ) {

						showEnterVR( displays[ 0 ] );

					} else {

						showVRNotFound();

					}
191

192
				} ).catch( showVRNotFound );
193

M
Mr.doob 已提交
194 195
			return button;

196 197
		} else {

M
Mr.doob 已提交
198 199 200
			var message = document.createElement( 'a' );
			message.href = 'https://webvr.info';
			message.innerHTML = 'WEBVR NOT SUPPORTED';
201

M
Mr.doob 已提交
202 203
			message.style.left = 'calc(50% - 90px)';
			message.style.width = '180px';
M
Mr.doob 已提交
204 205 206
			message.style.textDecoration = 'none';

			stylizeElement( message );
M
Mr.doob 已提交
207 208

			return message;
209 210

		}
M
Mr.doob 已提交
211

M
Mr.doob 已提交
212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229
	},

	// DEPRECATED

	checkAvailability: function () {
		console.warn( 'WEBVR.checkAvailability has been deprecated.' );
		return new Promise( function () {} );
	},

	getMessageContainer: function () {
		console.warn( 'WEBVR.getMessageContainer has been deprecated.' );
		return document.createElement( 'div' );
	},

	getButton: function () {
		console.warn( 'WEBVR.getButton has been deprecated.' );
		return document.createElement( 'div' );
	},
M
Mr.doob 已提交
230

M
Mr.doob 已提交
231 232
	getVRDisplay: function () {
		console.warn( 'WEBVR.getVRDisplay has been deprecated.' );
M
Mr.doob 已提交
233 234 235
	}

};