Thumb mislav Mislav Kvesic Monday, November 7, 2016

Nowadays, 360° panorama images are everywhere. To make a panorama image, one would think you need a good equipment and great photography skills. Well...Wrong! The only thing you need is some experience in coding with JavaScript. Today, I will play with two libraries that present images as 360° panorama views and test two libraries, first is Panorama Viewer by Pete R. which is the simplest I could find and Three.js which is most complex one I could find. Both are free and easy to start with.

If you ever talk with developers there is a good chance you’ll hear that nobody likes JavaScript. It is because it depends on global variables, lack of proper scoping, aggressive type coercion doctrine and much more. Some people tend to say that it will disappear because people will stop using it, but I would disagree. JavaScript was the first programming language that I began to understand and with which I had some kind of success. The first time I was able to develop something, make it appear on the browser and send it to friends without compiling. There are a lot of libraries and each day people add even more. Today, we’ll play with libraries that present images as 360° panorama views. Firstly, I will prepare the web-site where the libraries are going to be shown.

Step To Step Guide On How To Build 360° Panorama View With JS Libraries

Creating a site where you can see a library in action (the way it works) is really simple if you know basic Ruby on Rails. To find out how, follow my steps.
Firstly, create a new app with a few pages that will serve as examples for the libraries. Open your terminal and navigate to the folder in which you want to build this project and make a new app:

$ cd workspace/
$ rails new demorama

Then generate controller and pages:

$ cd demorama/
$ rails g controller pages

For the root path, I am going to use pages/index.html.erb and I will open the routes.rb by using nano:

$ nano config/routes.rb

And add the root to: "pages#index" line, so my config/routes.rb looks like this:

Rails.application.routes.draw do
  root to: "pages#index"
end

In the file pages/index, I will add two links that will lead to two examples of the panorama. Now, we need to include libraries and create those examples. The first example is a simple, but effective, a library called Panorama Viewer by Pete R.

 Library: Panorama Viewer 

Visit the Github page and download this library. Or you can do it through terminal:

$ cd vendor/assets/javascripts/
$ curl -o panorama_viewer.js https://raw.githubusercontent.com/peachananr/panorama_viewer/master/demo/jquery.panorama_viewer.js

And for CSS:

$ cd ..
$ cd stylesheets/
$ curl -o panorama_viewer.css https://raw.githubusercontent.com/peachananr/panorama_viewer/master/demo/panorama_viewer.css

Now include the library. You can do this by adding the library name to assets/javascript/application.js

$ cd ../../..
$ nano app/assets/javascripts/application.js

After you’ve done it, this file should look something like this:

//= require jquery
//= require jquery_ujs
//= require panorama_viewer
//= require turbolinks
//= require_tree .

You can repeat the same process in order to change CSS, but make sure you add it to the assets/stylesheets/application.css

$ nano app/assets/stylesheets/application.css

This is how it should look like:

/* 
*= require panorama_viewer
*= require_tree .
*= require_self
*/

Now, the only thing we need is the panorama image. If you don’t have a panorama image to use at the moment, feel free to download mine just for this purpose.
https://gitlab.com/kvesic.mislav/demorama/raw/master/app/assets/images/promenada.jpg

Next few steps should be repeated for each example. Add the image to demorama project and copy it in the app/assets/images folder.

$ cd
$ cd Downloads/
$ cp promenada.jpg ../workspace/demorama/app/assets/images

Now we can create a file in views/pages/ folder and call it first.html.erb

$ cd workspace/demorama/app/views/pages/
$ nano first.html.erb

And add this code:

<div class="panorama">
  <%= image_tag("promenada.jpg") %>
</div>
<script>
  // Use $(window).load() on live site instead of document ready. This is for the purpose of running locally only
  $(document).ready(function(){
    $(".panorama").panorama_viewer({
      repeat: true
    });
  });
</script> 

We should not forget to define routes, so we can actually reach the first.html.erb.

cd ../../..
nano config/routes.rb

And add the route. The file should look like this:

Rails.application.routes.draw do
  root to: "pages#index"
  get "first", to: "pages#first"
end

Also, add the link to your root page. Firstly open the index.html.erb

$ nano app/views/pages/index.html.erb 

And add the link

<h1> Demorama </h1>
<p> Few examples of 360° panorama images presented with JavaScript libraries. </p>
<%= link_to "First", first_path %>

Now, if you run the rails server command you should see the index page that leads to the first example (Panorama Viewer). The example shows only one image but when you drag the pointer, the image should move, so we get the effect which simulates the experience of you standing and rotating on the point where the image was taken. I have put this example to Heroku, here you can see the result: https://desolate-mountain-74634.herokuapp.com/first
Now, let’s take a look at a more advanced library.

Three.js

Three.js is a large library with many functionalities focusing on 3D graphics. We are now going to use one of their panorama / equirectangular example that is based on webgl. There are also other panorama examples, but I think this one is the most simple to setup. For the beginning, we should make a new html file that looks like the first.html.erb and I’ve just called mine second.html.erb. Then add the route to the routes.rb file and add a link to index.html.erb. After that, you need to add the three.js gem. You can find it here. Add the gem to the gemfile as you do usually, run bundle install and the last step is to add “//= require” three to app/assets/javascript/application.js.
This example simulates the person who sits in a gigantic ball and observes the panorama while 360° panorama is projecting on the surface of the ball. So again you could use the photo I have used (https://gitlab.com/kvesic.mislav/demorama/raw/master/app/assets/images/hotel_os.jpg), that’s not stretched correctly, or just find another equirectangular photo on Flicker. Then, add it to the app/assets/images folder.

Now you should open your second.html.erb file with your text editor and add some code to run the example. I took the basic code from that example and edited only the image location part in the initialization function. Here you can see the part that I have changed.

...
var material = new THREE.MeshBasicMaterial( {
map: new THREE.TextureLoader().load( '<%= image_url("hotel_os.jpg") %>' )
} );
...

You can download The whole content of the second.html.erb from my GitHub project (look at the end of the project) or find it in three.js examples.
Now, if we run the rails server and navigate to the second example (second.html.erb) we will see a nice panorama view provided by three.js: https://desolate-mountain-74634.herokuapp.com/second.


These are the most simple examples of showing panorama images. You don't need any fancy 360° camera or spend a lot of money to project the image on a sphere. If you want more than just projecting images you could allow the user to move from one room to another and provide the feeling of a virtual tour. In this case, you need to code a little bit more and experiment with three.js. If you like it so far do not miss the second part of this blog post where we'll teach you on how to do exactly that. :)



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