【Three.js】360°パノラマビューワーを作ってグリグリ操作出来るようにした（スマホ対応）

#<i class="fa fa-camera" style="font-size:1em;"></i> 概要

THETAやその他の360°全天球イメージ撮影デバイスで撮った画像で、バーチャルツアーとして360°のパノラマビューのコンテンツを作りたい場合、例えば「Panotour」や「Krpano」のようなオーサリングのソフトウェアを使うのが最も一般的ですが、これらのソフトは凄い高機能な反面、カスタマイズ性に欠けていて、ビルドされたコードも難解で、触るのにしても気が引けるので、やりたいことを中々、自由に簡単に実装することはできません。

やはりオーサリングソフトに依存せずに、自由に360°パノラマビューワーを実装するにはThree.jsのようなWebGLの技術を使い、自分で開発する必要があります。
(WebGLなのでスマホのOSが下位バージョンだと動きませんが・・・)

今回のビューワーで対応した項目は以下のとおり
> 	- 360°パノラマビュー表示
> 	- マウス操作
> 	- 回転アニメーション
> 	- PC全画面
> 	- ズーム
> 	- スマホ対応


コードは全て公開しますが、Three.jsの細かい部分の説明はしません。
最後にデモとGithubのリンクを用意してますので、そちらを参考にしてください。



#<i class="fa fa-camera" style="font-size:1em;"></i> Three.jsと必要なライブラリを読み込む

[Three.jsの公式サイト](http://threejs.org/)からファイル一式をダウンロードしてきて、その中から以下の2つのファイルを使います。

> 	- Three.min.js
> 	- OrbitControls.js

「OrbitControls.js」はダウンロードしてきたフォルダの「/examples/js/controls」にあります。

「Three.min.js」はメインの「Three.js」のminify化されたファイルで、「OrbitControls.js」はマウス&タッチ操作を行う為のファイルです。

これらと一緒に、メインのプログラムを書く「main.js」を作って、以下のように読み込みます。

```html:index.html
<div id="stage"></div>

<script src="three.min.js"></script>
<script src="OrbitControls.js"></script>
<script src="main.js"></script>
```


#<i class="fa fa-camera" style="font-size:1em;"></i> メインのプログラム

「main.js」に以下のコードを書きました。
シーンの作成〜レンダリングまで、オーソドックスに書いているので、分かり易いとは思います。
「helper（x軸、Y軸、z軸の補助線）」は必要に応じて、その部分を削除すれば問題無いです。

```js:main.js

(function(){

  var width = window.innerWidth,
      height = window.innerHeight;

  //scene

  var scene = new THREE.Scene();

  //mesh

  var geometry = new THREE.SphereGeometry( 5, 60, 40 );
	geometry.scale( - 1, 1, 1 );

  var material = new THREE.MeshBasicMaterial( {
	   map: THREE.ImageUtils.loadTexture( 'test.jpg' )
  } );

  sphere = new THREE.Mesh( geometry, material );
  scene.add( sphere );

  //camera

  var camera = new THREE.PerspectiveCamera(75, width / height, 1, 1000);
  camera.position.set(0,0,0.1);
  camera.lookAt(sphere.position);

  //helper

  var axis = new THREE.AxisHelper(1000);
  axis.position.set(0,0,0);
  scene.add(axis);

  //render

  var renderer = new THREE.WebGLRenderer();
  renderer.setSize(width,height);
  renderer.setClearColor({color: 0x000000});
  document.getElementById('stage').appendChild(renderer.domElement);
  renderer.render(scene,camera);

  //control

  var controls = new THREE.OrbitControls(camera,renderer.domElement);

  function render(){
    requestAnimationFrame(render);
    sphere.rotation.y += 0.05 * Math.PI/180;
    //画面リサイズ対応
    window.addEventListener( 'resize', onWindowResize, false );
    renderer.render(scene,camera);
    controls.update();
  }
  render();
  
  
  function onWindowResize() {
	camera.aspect = window.innerWidth / window.innerHeight;
	camera.updateProjectionMatrix();
	renderer.setSize( window.innerWidth, window.innerHeight );
  }
  

})();

```

#<i class="fa fa-camera" style="font-size:1em;"></i> デモ

[DEMO](http://king-panda.github.io/panorama/)

[![Panorama_Example.png](https://qiita-image-store.s3.amazonaws.com/0/67591/fbc806b9-ba9c-d441-62f7-a116a4df96e5.png)](http://king-panda.github.io/panorama/)

ちなみにデモで使っている画像は、本日発売のTHETA Sで撮影しました。
スマホのバージョンはAndroid5(nexus5)とiOS9(iphone6S)で動いているのを確認済みです。

サンプルの置き場はこちらです。
https://github.com/king-panda/panorama

#<i class="fa fa-camera" style="font-size:1em;"></i> 最後に

高価格のオーサリングソフトを買わなくても、Three.jsを使えば、シンプルな360°パノラマビューワーはすぐに作れます。UIの実装は大変ですが、思い通りに作れますし、サーバサイドのシステムとの連動も考えれば、ここに時間をかける価値は十分有ると思います。
次は、複数枚画像の表示切り替えや動画対応、スマホのジャイロ対応、二眼対応等もやっていきます。