I personally hate supporting mobile for WebXR applications, but many users will stumble across them with their phones so we might as well let them get a taste of our apps. And fortunately it's easy to do (everything has been pretty easy so far hasn't it?)
It might be easy for you all now, but everything was changing so rapidly with the WebXR API and the browsers supporting it in 2019 that I was rewriting my code every month because of breaking changes and new ways of doing things. Everything is MUCH more stable now, so lucky you...
In this tutorial, we'll be extending our code from Part 3 to let Mobile users look around using their phone. Once again, three.js has a community supported component to handle this called DeviceOrientationControls.js which utilizes the rotation of the phone
Start by placing
/scripts/three/examples/jsm/controls/ because it has a relative import to three.module.js
Now before we edit
SessionHandler.js to use DeviceOrientationControls, let's edit
setup.js to set our device type as Mobile when applicable. How do we know when a user is on a Mobile device?
Truthfully, there's no good way as far as I know. We set the deviceType as Pointer when we knew the user wasn't on an XR Device. Following that same branch of logic we'll assume that if the user doesn't have a Pointer that they're on a Mobile device
This doesn't handle all cases, as some phones will register as having a pointer. But it's more trouble than it's worth to deal with those users. If you know a better way to determine if a user is coming from a mobile device, post a comment!
Here's what our updated
setup.js looks like
Now we can edit SessionHandler.js to check if the deviceType is MOBILE and if so, create a button that says Tap to Start along with setting
this._controls to an instance of DeviceOrientationControls. We'll worry about hiding the button after tapping later
Make sure to import DeviceOrientationControls
If we try and run this, we get an error. Why? DeviceOrientationControls behaves a little differently from PointerLockControls in that when we instantiate it, it will immediately request the device for permission to access orientation information. Similar to PointerLockControls, we need a user action before we request a lock, or in this case access to orientation data
So let's replace where we instantiate DeviceOrientationControls with this
Now it doesn't throw an error, but it's still not working. What gives? Well by taking a peak inside DeviceOrientationControls.js we see we need to call an update function. Let's add an update function to our SessionHandler and call it from the update function in Main. Here's what our update in
SessionHandler.js should look like
You can see we added a little check to make sure we only call
this._controls.update() when it is indeed possible so we don't throw any errors
We can now look around by just rotating your mobile device. But wait, doesn't that Tap to Start button look kind of small to you? We can fix this by adding
<meta name="viewport" content="width=device-width, initial-scale=1"> inside the
head tag of
There we go, now we have a simple WebXR app that works on XR Device Browsers, Desktop / Laptop Browsers, and Mobile Browsers. Nice job!
Feeling generous/want to support me in writing tutorials? Then buy me a coffee, which I'll probably use for boba or almonds (raw and unsalted you heathens) because I don't like coffee