frame academy

Learn how to create immersive, cross-platform webxr sites.

project 4: creating a webxr photosphere gallery with javascript

Part 2: using the mouse + vr controllers

I hope you also took a crack at the challenge for Part 1! If you do the challenges, you'll be building your own immersive website that works on desktop, mobile, or VR.

Remember that if you have questions or want to share your work-in-progress, feel free to ask in our online community, or on Twitter with the hashtag #frameacademy

cursors on desktop + mobile mode

There's a small part of the index.html file of the starter project that I didn't talk about in Part 1. It starts at line 25. Take a peek:

<a-entity id="camera" position="0 1.6 0" camera look-controls wasd-controls>        
  <a-entity cursor="rayOrigin: mouse"></a-entity>      
</a-entity>            

<a-entity laser-controls="hand: right"></a-entity>

We saw in the first few projects that A-Frame creates a default camera automatically, but I made my own camera in this project because I want to configure it a bit. So, this entity has the camera component, the look-controls component (this is what lets you click and drag the mouse to rotate the view of the camera), and the wasd-controls component (this is what lets you press the wasd keys to move the camera around the scene). All of these components are included with A-Frame and you can learn more about them in the A-Frame documentation if you want.

As a child of my camera entity, I've made an entity with the cursor component. This is another component that comes with A-Frame. The cursor component is what lets us actually click on or hover on stuff in the scene, so it's essential for any site that has interactivity in it!

I've made the entity with cursor on it a child of the camera because I want the cursor to be active no matter where the camera is looking in the scene. I checked out the documentation for the cursor component to see the properties I could configure. There's a lot of stuff we haven't learned about yet, but don't sweat it:

For my starter project, I want the cursor to be linked to the mouse so that users on desktop can simply point and click with the mouse to interact with stuff. To do that, I can set the value of the rayOrigin property to "mouse":

<a-entity cursor="rayOrigin: mouse"></a-entity>               

On mobile (non-VR mode), you can just tap on the screen to "click" on something.

Alternatively, you can also link the cursor to an entity by setting rayOrigin: entity if you wanted a visual cursor. This is difficult to explain, but you can see an example on this WebXR site I made. See how there's a tiny circular cursor that moves along with the camera that you can use to click on stuff? That's an entity-based cursor, not a mouse-based cursor. Take a peek at the visual, entity-based cursor in action:

Back to my starter project, though. Why did I want a mouse-based cursor for desktop/mobile? I think they are a bit easier to understand because people are used to simply pointing and clicking with the mouse on desktop or tapping the screen to interact on mobile. There are advantages to an entity-based visual cursor if you want your project to work on devices like Google Cardboard that don't have controllers. If you're making a WebXR project and it's important that it works on Google Cardboard, let me know and I'll help you out.

virual reality controllers

The previous section covers desktop/mobile mode, but what about viewing your WebXR site in VR, like from an Oculus Rift/Go/Quest, Vive, WinMR, GearVR, etc? Take a peek at this code on line 29 of the starter project, right below our camera entity:

<a-entity laser-controls="hand: right"></a-entity>

The laser-controls component automatically creates tracked controllers that will show up for those viewing your WebXR site in VR, and you can give the hand property a value of left or right to make a laser shoot out of either the left or right controller. You can use this laser to "click" on things in your scene! That's why my laser-controls component is set to "hand: right".

On devices with one controller like the Oculus Go, the laser beam will shoot out of your one controller, but on headsets with two controllers, it will shoot out of the hand you've configured with the hand property. Here I am using a VR controller to "click" on the photosphere in the back left of the gallery, triggering the interaction I've set up (that we will learn about soon, I promise!):

Wait? Am I saying that with one line of HTML we can add tracked controllers and a laser pointer for "clicking" across just about any VR headset? And that with 5 lines of code total we have the ability to interact with our WebXR sites across nearly all VR devices, laptop/desktop, and mobile?

Yes, I am. And yes, that's awesome to an epic degree.

challenge #2: try out "clicking" on the devices you have

This challenge is pretty simple, but I'd like you to simply load up your project on as many devices as you can to test out interactivity and "clicking". The way to test is to try to "click" on the sphere in the back left corner of the gallery to make it expand. I'll show you how I actually set up that feature in the next part.

For fun, if you want to change the color of the laser in laser-controls, you can add a line component to that entity and give its color property a color value! For example: <a-entity laser-controls="hand: right" line="color: red"></a-entity>

< go back to part #1
explore the starter project
Move on to part #3 >
diving into javascript