2021年10月1日
プログラミング
JavaScriptでA-Frameのカメラの向きを制御する


はじめに
この記事では、JavaScriptでA-Frameのカメラの向きを制御する方法と、仕組みについて書こうと思います!
こんな方におすすめ
- A-Frameを触ったことがある方
- カメラの向きを正面にリセットしたい
- カメラを特定の方向に向けたい
- カメラの向きを変更するイメージが沸かない
A-Frameとは
簡単にAR/VRを実装できるフレームワークです。
HTMLファイルにタグを記述していくだけで簡単に実装でき、
JavaScriptを書くことでクリック時のイベントなどを実装することも可能です。
カメラの向きを正面にリセットする
ベースとなるHTML
まずはHTMLの記述で、a-camera
をa-entity
で囲みます。
<a-entity id="camera-wrapper" rotation="0 0 0" position="0 1.6 0">
<a-camera id="camera" position="0 0 0" look-controls="" wasd-controls="enabled: false"></a-camera>
イメージはこんな感じです。
黄色い矢印が、カメラの向いている方を指しています。
JavaScriptでのカメラ制御
マウスのドラッグなどでカメラの向きを変えると、このように<a-camera>
のみ向きが変わります。
ここでカメラを最初の向きにリセットしたい場合は、
カメラが動いた分、<a-entity>
を反対方向に回転させることで正面に向けることができます。
<a-entity>
を回転させると、内包されている<a-camera>
も一緒に回転します。
これはJavaScriptで実装する必要があり、以下のようになります。
const cameraWrapper = document.getElementById("camera-wrapper")
const camera = cameraWrapper.querySelector("a-camera")
const cameraRotation = camera.getAttribute("rotation") // <a-camera>の現在のrotation(回転)を取得</a-camera>
// <a-entity>のY軸の回転を、<a-camera>のY軸の回転分、マイナスする
cameraWrapper.setAttribute("rotation", { y: -cameraRotation.y })
これでカメラを正面に向けることができました。
camera.setAttribute(“rotation”, …)ではカメラを動かすことはできないので注意!
POINT!!
カメラを囲むentityを、カメラの回転分マイナスするとカメラが正面を向く!正面が0度
応用:カメラを特定の方向に向ける
カメラの向きをリセットではなく、あるオブジェクトの方向に向ける方法です。
setAttributeのrotationでYに任意の数値を入れることで特定の方向に向けることができます。
cameraWrapper.setAttribute("rotation", { y: 45 })
さらに、カメラの座標と、対象となるオブジェクトの座標が分かれば、
数学の授業で習った「三角関数」を用いて簡単にオブジェクトへの角度を求めることができます!
// <a-entity id="camera-wrapper" rotation="0 0 0" position="0 1.6 0">
const cameraPosition = {
x: 0,
y: 1.6,
z: 0
}</a-entity>
// カメラを向ける対象となるオブジェクトの座標を取得
const targetPosition = document.getElementById("target").getAttribute("position")
// 三角関数を用いて、2点の座標からラジアンを求める
// 今回高さは関係ないのでYは無視します
const radian = Math.atan2(cameraPosition.x - targetPosition.x, cameraPosition.z - targetPosition.z)
// ラジアンを"角度"に変換
const degree = Math.floor(radian * (180 / Math.PI))
cameraWrapper.setAttribute("rotation", { y: degree })
これでオブジェクトがどこにあっても、カメラを向けることができるようになりました!
POINT!!
カメラからオブジェクトへの角度は、対象物とカメラ、2点の座標があれば三角関数で角度が求められる!
おまけ:カメラの角度を直接変える
これまでカメラを囲む<a-entity>
を回転させる方法を紹介しましたが、
カメラの向きを直接変更する方法もあります!
const camera = document.querySelector("a-camera")
// 3軸ともリセット
// ここに代入する数値は角度ではなくラジアン
camera.components["look-controls"].yawObject.rotation.y = 0
camera.components["look-controls"].pitchObject.rotation.x = 0
camera.components["look-controls"].pitchObject.rotation.z = 0
PCでは問題ないのですが、スマートフォンのモーションセンサーを有効にしている場合は
モーションセンサーの方が優先されるため、JavaScriptで制御することはできません。
そのためカメラを囲む<a-entity>
を回転させる方法をご紹介しました。
モーションセンサーを使用すると、スマートフォンの動きに合わせてカメラの視点が変えられます。
look-controlsコンポーネントの追加で有効になります。
私はカメラを上下左右正面に戻したい時は、左右(Y軸)は<a-entity>
を回転させ、
上下(X軸)はPCのみの対応として<a-camera>
を回転させました!
const cameraWrapper = document.getElementById("camera-wrapper")
const camera = cameraWrapper.querySelector("a-camera")
const cameraRotation = camera.getAttribute("rotation")
// 左右(Y軸)の回転。PC/SP共通
cameraWrapper.setAttribute("rotation", { y: -cameraRotation.y })
// 上下(X軸)の回転。PCのみ対応
camera.components["look-controls"].pitchObject.rotation.x = 0
POINT!!
モーションセンサーを使用する場合は、カメラの向きはスマートフォンの動きが反映される
さいごに
今回はA-FrameのカメラをJavaScriptで制御する方法をご紹介しました。
この方法を使えば、メニューをクリックするとカメラが該当のオブジェクトに向く、なんて実装も可能になります!
この記事がお役に立てれば幸いです。
最後までご覧いただき、ありがとうございました!
JavaScriptのお仕事に関するご相談
Bageleeの運営会社、palanではJavaScriptに関するお仕事のご相談を無料で承っております。
zoomなどのオンラインミーティング、お電話、貴社への訪問、いずれも可能です。
ぜひお気軽にご相談ください。
この記事は
参考になりましたか?
0
0
関連記事

2018年7月6日
【js】jQueryでできるハンバーガーメニューの作成

2018年6月18日
プログレスバーを簡単に実装できるprogressbar.js

2018年5月8日
画像に簡単にアニメーションをつけるcurtain.js

2018年2月14日
【js】jQueryでできるアコーディオンメニューの作成

2017年9月4日
【JS】スクロールした時にCSSanimationを発動させる「scrollMonitor」
簡単に自分で作れるWebAR
「palanAR」はオンラインで簡単に作れるWebAR作成ツールです。WebARとはアプリを使用せずに、Webサイト上でARを体験できる新しい技術です。
palanARへ
palanでは一緒に働く仲間を募集しています
正社員や業務委託、アルバイトやインターンなど雇用形態にこだわらず、
ベテランの方から業界未経験の方まで様々なかたのお力をお借りしたいと考えております。
運営メンバー

Eishi Saito 総務
SIerやスタートアップ、フリーランスを経て2016年11月にpalan(旧eishis)を設立。 マーケター・ディレクター・エンジニアなど何でも屋。 COBOLからReactまで色んなことやります。
sasakki デザイナー
アメリカの大学を卒業後、日本、シンガポールでデザイナーとして活動。

やまかわたかし デザイナー
フロントエンドデザイナー。デザインからHTML / CSS、JSの実装を担当しています。最近はReactやReact Nativeをよく触っています。
Sayaka Osanai デザイナー
Sketchだいすきプロダクトデザイナー。シンプルだけどちょっとかわいいデザインが得意。 好きな食べものは生ハムとお寿司とカレーです。

はらた エンジニア
サーバーサイドエンジニア Ruby on Railsを使った開発を行なっています

こぼり ともろう エンジニア
サーバーサイドエンジニア。SIerを経て2019年7月に入社。日々学習しながらRuby on Railsを使った開発を行っています。

ささい エンジニア
フロントエンドエンジニア WebGLとReactが強みと言えるように頑張ってます。

Damien
WebAR/VRの企画・開発をやっています。森に住んでいます。

ゲスト bagelee

かっきー

まりな

suzuki
miyagi

ogawa
雑食デザイナー。UI/UXデザインやコーディング、時々フロントエンドやってます。最近はARも。

いわもと
デザイナーをしています。 好きな食べ物はラーメンです。

taishi kobari
フロントエンドの開発を主に担当してます。Blitz.js好きです。

kubota shogo
サーバーサイドエンジニア。Ruby on Railsを使った開発を行いつつ月500kmほど走っています!
nishi tomoya

aihara
グラフィックデザイナーから、フロントエンドエンジニアになりました。最近はWebAR/VRの開発や、Blender、Unityを触っています。モノづくりとワンコが好きです。
nagao
SIerを経てアプリのエンジニアに。xR業界に興味があり、unityを使って開発をしたりしています。

Kainuma
サーバーサイドエンジニア Ruby on Railsを使った開発を行なっています

sugimoto
asama
ando
iwasawa ayane

oshimo
異業界からやってきたデザイナー。 palanARのUIをメインに担当してます。 これからたくさん吸収していきます!