CMS化したい
昨日テストしたPanolensが使えそうなので、HTMLやJavaScriptが使えない人でも手軽に360VRを作れる様にCMS化していこうと思います。
目指すは無料版InstaVRです。
この手のプログラミングは素人ながら、遠隔操作で1対複数人でVR空間内をアテンドできる仕組みを温めているところです。
今回は、ホットスポットをクリックで追加していく機能を追加してみます。この機能は、CMS化する時の編集画面に使えそうです。
クリックした座標を取得する機能を追加する
標準機能でもマウスカーソルの座標を表示できる
Panolensには、Ctrlを押しっぱなしにするとマウスカーソル位置のワールド座標を表示する機能があります。この機能を有効化するには、Viewerオブジェクト作成時にoutputオプションを指定します。
var viewer = new PANOLENS.Viewer({output: 'overlay'});
デバッグ時には便利なのですが、この機能だけでは目的の動作はできないので、独自の関数を追加していきます。
ソースコード
Panolens.jsを開いて、一番下に関数を追記します。
この関数は、パノラマ画像のクリック位置を取得してワールド座標を返します。引数にタイプを設定できる様にしていて、初期値の 'position' はVector3で座標を返し、'console' を指定するとブラウザのコンソールに座標を表示します。
panolens.js
PANOLENS.Viewer.prototype.getPosition = function (type ='position') {
//パノラマとの交差を取得
const intersects = viewer.raycaster.intersectObject(this.panorama, true);
if (intersects.length > 0) {
//ワールド座標に変換
const point = intersects[0].point.clone();
const converter = new THREE.Vector3(-1, 1, 1);
const world = this.panorama.getWorldPosition(new THREE.Vector3());
point.sub(world).multiply(converter);
if (point.length() === 0) { return null; }
else {
switch (type) {
//文字列でコンソールへ出力
case 'console':
str = `${point.x.toFixed(2)}, ${point.y.toFixed(2)}, ${point.z.toFixed(2)}`;
console.info(str);
break;
//Vector3で返す
case 'position':
pos = new THREE.Vector3(point.x.toFixed(2), point.y.toFixed(2), point.z.toFixed(2));
return pos;
break;
default:
break;
}
}
}
}
次に、index.htmlにクリックイベントを追加します。
実行すると、クリックする度にコンソールに座標が出力されます。
index.html
//クリックイベントを追加
panorama.addEventListener('click', function () {
//クリック位置を取得
viewer.getPosition('console');
});
クリックした場所にホットスポットを作成する機能を追加する
少し書き換えて、クリックした場所にホットスポットを追加作成できる様にしてみます。クリックイベントにホットスポット(Infospot)を作成する処理を書いて、positionに座標を割り当てるだけです。
panolensではパノラマをクリックする度にホットスポットの表示非表示が切り替わってしまう仕様になっているので、これを無効化しないと正しく動作しません。クリック後も表示状態を維持させるためにtoggleInfospotVisibilityをfalseに手動設定します。
index.html
//クリックイベントを追加
panorama.addEventListener('click', function () {
//クリック位置を取得
pos = viewer.getPosition();
//Infospot作成
var infospot = new PANOLENS.Infospot();
infospot.position.set(pos.x, pos.y, pos.z);
panorama.add(infospot);
//Infospotを表示状態にする
panorama.toggleInfospotVisibility(false);
});