frame academy

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

project 5: using audio, video, and 360 video in your webxr sites

Part 4: 360 Video / videospheres

I hope you also took a crack at the challenge for Part 3! 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

the a-videosphere entity

Just like with a-video, there's an element you can use to bring videospheres into your A-Frame projects: a-videosphere

Just as we did with our audio and video, for the src attribute on this entity we can use the id of the videosphere file that we've already uploaded to our Glitch assets folder and preloaded inside of a-assets in Part 1. You can see my preloaded videosphere asset in the starter project on line 27 of the HTML. It has id="spherevidclip". So, our a-videosphere entity starts off like this:

<a-videosphere src="#spherevidclip"></a-videosphere>

That's a great start, but just like our photosphere at the back left of the gallery. I want to nest my videosphere under a parent entity that will hold the videosphere, a little box under it, and a caption. I also want my videosphere to start out as a small sphere that the user will click on to expand, so I'm going to set the radius attribute on my videosphere entity to radius=".7".

The a-videosphere entity is really an a-sphere with a video texture on it, so you can use properties like radius that you would typically use on a-sphere.

Check out the parent entity with the box, videosphere, and caption nested inside of it below on line 79.

creating the videosphere player component

We want the videosphere to expand when users click on it, just as we did with the photosphere, so we're going to make a component that does this for us. All in all we want our component to do a few things:

- expand the videosphere so that it makes up the background of the scene
- play the videosphere so that it plays on all devices
- cause the elements in the scene with class="homeworld" to disappear so that the videosphere is in full view

Doing all of these things will combine things that we've done before in our sphereexpand component and our videocontrols component, so it shouldn't be too tough.

First, I made a new JavaScript file in Glitch and named it public/js/videosphereexpand.js

I made a new component in that file by copying and pasting in the code from the componentstarter.js file you can see in the Glitch project, and I gave the component a name of videosphereexpand:

AFRAME.registerComponent('videosphereexpand', {
init: function () {  


Inside of init, I make references to the elements in the scene that I need to modify: the videosphere asset itself inside of a-assets (just as we did in the videocontrols.js component), the a-videosphere entity, and all of the entities with class="homeworld" (just as we did in sphereexpand.js). In my HTML, the videosphere asset in a-assets has id="spherevidclip", the a-videosphere entity has id="videosphereentity", and all of the entities that should disappear once a sphere is expanded have class="homeworld", so here's how I made references to all of them in my new component.

let videosource = document.querySelector('#spherevidclip');      
let videosphere = document.querySelector("#videosphereentity");      
let homeworldelements = document.querySelectorAll(".homeworld");

Now, I need to define the function that does what I want once the user clicks on the videosphere. I'm going to call the function videosphereloader, so it starts off looking like this:

let videosphereloader = () => {

Inside the curly braces we put all the code we want to run, or execute, when this function gets called. We're just defining the function at this stage, not "calling" it.

Just as we did in the previous part of this project with video, we can use .play right on the video asset, which we've made a reference to as videosource above. So that looks like:;

I also want to change the radius of the a-videosphere entity so that the sphere takes up the whole viewing perspective, and we can do that with something we've already learned: .setAttribute

Remember, .setAttribute lets you add or modify attributes on your entities. In this case, we want to set the radius attribute so that instead of being ".7" (its starting value in the HTML), it's much bigger. So I'll do this, using the videosphere variable that I made above with let videosphere

videosphere.setAttribute("radius", "4200");

Why did I make it 4200? Well, we have an a-sky in our scene, and I saw in the documentation for a-sky that the a-sky has a radius of 5000. I wanted the radius of this to be smaller so that it wouldn't conflict with the a-sky at all.

Finally, I do the same thing to the homeworldelements that I did in Project 4 where I iterated through the list of homeworldelements and for each one, I set its visible component to false by doing a .setAttribute on the visible attribute.

homeworldelements.forEach((homeworldelement) => {      
homeworldelement.setAttribute("visible", false)})      

That will wrap up the function. Finally, I add an eventListener that will call my new videosphereloader function as soon as a click is detected on this - with this being whatever entity I end up attaching this entire component to in my HTML.

this.el.addEventListener('click', videosphereloader);

See the full component by checking out the embedded project above and viewing the public/js/videosphereexpand.js file.

final steps

Finally, we need to import our new JavaScript file as a script element inside the head of our HTML document, and then of course attach the videosphereexpand component to an entity in our scene. I've attached it to the a-videosphere entity on line 81 of my HTML so that the this in the component will refer to the a-videosphere entity, since that's what I want the click eventListener to be added to. That way, when users click the videosphere in the scene, it will run our new function.

I've also made a slight adjustment to our backhome component that we made in Project 4, so that just in case users click that backhome button after they've expanded the videosphere, it makes sure to bring the radius of the a-videosphere back to its starting value of .7

Try out all out in the project by clicking on the videosphere. It's the sphere to the right of the photosphere.

challenge #4: set up your own videosphere

See if you can set up this same functionality in your own project, using your own asset. Remember, only equirectangular videospheres will work well. Try it out with multiple photospheres if you want, but keep in mind that the more assets you load in your project, the longer it will take for your site to load!

At the end of this project, if you've gone through all of the challenges you should have some audio, video, and videosphere functionality inside your own WebXR site. That's pretty exciting stuff. :) If you'd like, share your work to the Frame Academy Gallery so that other learners can check it out and learn from it!

If you'd like to support the creation of more Frame Academy Projects, please consider donating using the button below.

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

Did you get value from this Frame Academy project? Do you want support the creation of more?

< go back to part #3
2D Video
see other Frame Academy Projects