8686 </ head >
8787 < body >
8888
89+ < h1 > KJSL: Minor variant to include PR #71</ h1 >
8990 < div class ='container ' id ='container '>
9091 < header class ='header '>
9192 < div id ='nav '>
@@ -109,6 +110,7 @@ <h2 class='tagline'>Sample Pages</h2>
109110 < div >
110111 < img id ='canhazimg ' style ='width: 32px; float: left; '> </ img >
111112 < p id ='canhazwebxr ' style ='margin-left: 48px; '> </ p >
113+ < button id ='request-permissions ' style ='display: none; padding: 4px 8px; '> Request Permissions</ button >
112114 </ div >
113115 < script >
114116 function isMobile ( global ) {
@@ -117,22 +119,42 @@ <h2 class='tagline'>Sample Pages</h2>
117119 return check ;
118120 } ;
119121
122+ function isiOS ( ) {
123+ return / i P h o n e | i P a d | i P o d / i. test ( navigator . userAgent ) ;
124+ }
125+
126+ async function requestPermissions ( ) {
127+ let motionPermission = 'granted' ;
128+
129+ try {
130+ if ( typeof DeviceMotionEvent !== 'undefined' && typeof DeviceMotionEvent . requestPermission === 'function' ) {
131+ motionPermission = await DeviceMotionEvent . requestPermission ( ) ;
132+ }
133+ } catch ( error ) {
134+ console . log ( "Waiting user to grant permissions" ) ;
135+ }
136+
137+ if ( motionPermission === 'granted' ) {
138+ canhazElement . innerText = "Your granted motion permissions and should be able to use this demo on Safari for iOS"
139+ canhazImg . src = "media/textures/check-button.png" ;
140+ permsButton . style . display = "none" ;
141+ document . querySelectorAll ( "article" ) . forEach ( l => l . classList . remove ( "warning" ) ) ;
142+ } else {
143+ console . log ( "Could not get permissions" ) ;
144+ }
145+ }
146+
147+ let permsButton = document . getElementById ( 'request-permissions' ) ;
120148 let canhazElement = document . getElementById ( 'canhazwebxr' ) ;
121149 let canhazImg = document . getElementById ( 'canhazimg' ) ;
122- if ( 'xr' in navigator ) {
123- canhazElement . innerText = "Your browser implements the WebXR API and may be able to run Virtual Reality or Augmented Reality experiences if you are using a supported OS and the appropriate hardware."
124- navigator . xr . isSessionSupported ( 'immersive-vr' ) . then ( ( supported ) => {
125- const span = document . createElement ( 'span' ) ;
126- span . innerText = supported ? '✔️- VR support detected' : '❌ - VR support not detected' ;
127- canhazElement . appendChild ( document . createElement ( 'br' ) ) ;
128- canhazElement . appendChild ( span ) ;
129- } ) ;
130- navigator . xr . isSessionSupported ( 'immersive-ar' ) . then ( ( supported ) => {
131- const span = document . createElement ( 'span' ) ;
132- span . innerText = supported ? '✔️- AR support detected' : '❌ - AR support not detected' ;
133- canhazElement . appendChild ( document . createElement ( 'br' ) ) ;
134- canhazElement . appendChild ( span ) ;
135- } ) ;
150+ if ( isMobile ( window ) && isiOS ( ) ) {
151+ canhazElement . innerText = "Safari for iOS requires manually grant motion permissions to use WebXR"
152+ canhazImg . src = "media/textures/info-button.png" ;
153+ permsButton . style . display = "block" ;
154+ permsButton . addEventListener ( 'click' , requestPermissions ) ;
155+ document . querySelectorAll ( "article" ) . forEach ( l => l . classList . add ( "warning" ) ) ;
156+ } else if ( 'xr' in navigator ) {
157+ canhazElement . innerText = "Yes! Your browser supports WebXR and can run Virtual Reality and Augment Reality experiences if you have the appropriate hardware."
136158 canhazImg . src = "media/textures/check-button.png" ;
137159 } else if ( 'getVRDisplays' in navigator ) {
138160 canhazElement . innerText = "Your browser does not support WebXR, but does support the deprecated WebVR API. You may be able to run Virtual Reality experiences on sites that use the WebXR Polyfill, like this one!"
@@ -173,23 +195,23 @@ <h2 class='tagline'>Sample Pages</h2>
173195 { title : 'Room Scale' , category : 'Basics' ,
174196 path : 'room-scale.html' ,
175197 description : 'Demonstrates using a "local-floor" reference space to provide room scale tracking.' } ,
176-
198+
177199 { title : 'Input Tracking' , category : 'Input' ,
178200 path : 'input-tracking.html' ,
179201 description : 'Demonstrates basic tracking and rendering of XRInputSources.' } ,
180-
202+
181203 { title : 'Input Profiles' , category : 'Input' ,
182204 path : 'input-profiles.html' ,
183205 description : 'Demonstrates loading appropriate controller models based on the XRInputSources profiles array.' } ,
184-
206+
185207 { title : 'Input Selection' , category : 'Input' ,
186208 path : 'input-selection.html' ,
187209 description : 'Demonstrates handling \'select\' events generated by XRInputSources.' } ,
188-
210+
189211 { title : 'Controller State' , category : 'Input' ,
190212 path : 'controller-state.html' ,
191213 description : 'Demonstrates responding to controller state from an XRInputSource\'s gamepad attribute.' } ,
192-
214+
193215 { title : 'Hand Tracking' , category : 'Input' ,
194216 path : 'immersive-hands.html' ,
195217 description : 'Demonstrates using the Hand Tracking API to track the user\'s hands.' } ,
@@ -228,7 +250,7 @@ <h2 class='tagline'>Sample Pages</h2>
228250 { title : 'Hit Test' , category : 'AR Basics' ,
229251 path : 'hit-test.html' ,
230252 description : 'Demonstrates using the Hit Test API to place virtual objects on real-world surfaces.' } ,
231-
253+
232254 { title : 'Hit Test with Anchors' , category : 'AR Basics' ,
233255 path : 'hit-test-anchors.html' ,
234256 description : 'Demonstrates using the Hit Test API together with the Anchors API to place virtual objects on real-world surfaces.' } ,
0 commit comments