Thumb mislav Mislav Kvesic Thursday, December 22, 2016

This is the second part of my first blog where I have written about Presenting Your 360 Panorama Images With JavaScript. It's time to show you how to navigate through virtual rooms with JavaScript. This part is a bit more advanced but we'll guide your through it step by step. :)

In order not to change the code in the last example, I added a new example and called it the third. It’s the same as the last one, but this one has an icon. 

More Than Just Showing Round Images

You can notice that there is a possibility to add more pins/icons if you need. Just add as many as you like to the group. I will add just one which, when you click on it, leads to another panorama image that simulates the outside view. You should put the code that adds the icon to the image in the initializer and adds the group to the scene. See here:

...
var pin = THREE.ImageUtils.loadTexture( '<%= image_url("exit.png") %>' );
var marker = new THREE.SpriteMaterial( { map: pin } );
var sprite = new THREE.Sprite( marker );
sprite.name = "exit";
sprite.position.set( -50, 2, 50 );
sprite.scale.set(20, 20, 1 );
group = new THREE.Object3D;
group.add(sprite);
scene.add(group);
...

Notice also the sprite.name = "exit"; line. I added the name of the sprite because I will be able to find it again when I click on it.

Now that we have an icon, let’s make it clickable. We add an eventlistener, Raycaster and Vector2. This is how the code should look like:

...
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
document.addEventListener( 'click', function ( event ) {
event.preventDefault();
mouse.x = ( event.clientX / renderer.domElement.clientWidth ) * 2 - 1;
mouse.y = - ( event.clientY / renderer.domElement.clientHeight ) * 2 + 1;
raycaster.setFromCamera( mouse, camera );
var intersects = raycaster.intersectObjects( scene.children, true );
for ( var i = 0; i < intersects.length; i++ ) {
  if (intersects[i].object.name=="exit") {
    mesh.material.map = THREE.ImageUtils.loadTexture( '<%= image_url("promenada2.jpg") %>' );
    mesh.material.needsUpdate = true;
}
}, false );
...

All these codes can be found on StackOverflow and three.js documentation. I will say only a few words about the for loop and this line here: var intersects = raycaster.intersectObjects( scene.children, true ). It is set true because without it the for loop would not find the sprite. The for loop goes through everything what is in intersects and when it finds the object with the right name, in this case “exit”, it will do what we want it to do. In this case, it changes the image.

Again, I made a simple panorama with my smartphone and named it promenada2. The code works without this line mesh.material.needsUpdate = true as well.

In addition, I disabled the part that rotates the image when we aren’t using the mouse because it’s a bit annoying :) . In the update function, I commented the part that always adds 0.1 to the longitude. Here is how:

...
function update() {
 if ( isUserInteracting === false ) {
  //lon += 0.1;
 }
}
...

When you open the third example you can see the same image you’ve seen in the second example, but there is an icon which, when you click on it, leads you to the next image.

Oh look! The icon doesn’t fit well into the second image - it’s because it has the same position attributes. The code would need a few fixes to look better, but in this example, its enough to get you to the point. :) You can find the whole project here

If you want to see a real panorama image implemented on to the website, check our project for Ethnology Center of Baranja’s Heritage and let us know what you think! :)



Cookies help us deliver our services. By using our services, you agree to our use of cookies.