はじめに
この記事は Babylon.js Advent Calendar 2024
の、15日目の記事です
何度かに分けて、スマホのセンサーにアクセスして玉転がしをするページを作成してみます。
今回の内容。
スマートフォンには、デバイスの動きや向きを検知する ジャイロセンサー や 加速度センサー が搭載されており、これらのセンサーの値はブラウザからでもアクセスすることができます。
その値を画面に表示する方法についてまとめました。
デバイスのセンサー類にアクセスする
まずはジャイロセンサーにアクセスしてみます。
DeviceOrientationEvent が、デバイスの方向の情報を取得するイベントです。方向が変更されるたびにイベントが発火し、以下の情報を取得できます。
1.alpha(スマホの回転)
2.beta(スマホの上下の傾き)
3.gamma(スマホの左右の傾き)
図にすると以下のようになります。
では、ジャイロセンサーにアクセスしてみましょう。
ジャイロセンサーにアクセスするため、DeviceOrientationEventイベントを登録してイベントの発火でセンサーの値を表示するようにしてみます。
DeviceOrientationEventをリスナーに登録して、発火したeventから alpha、beta、gamma の値を作用しているだけです。
//deviceorientationイベントにhandleOrientation関数を登録し
window.addEventListener('deviceorientation', handleOrientation);
//センサーの値をテキスト欄に表示する。値はeventから収集
const handleOrientation = (event) => {
const alpha = (event.alpha || 0);
const beta = (event.beta || 0) ;
const gamma = (event.gamma || 0) ;
alphaText.text = `alpha: ${alpha.toFixed(2)}°`;
betaText.text = `beta: ${beta.toFixed(2)}°`;
gammaText.text = `gamma: ${gamma.toFixed(2)}°`;
};
ジャイロセンサーへのアクセス確認
playgroundに登録したので、スマートフォンで以下のURLにアクセスしてみます。
https://playground.babylonjs.com/#2S9H94#18
以下のように画面が表示されるはずです。
センサー読み取り開始ボタンを押して処理を始めましょう。
iPhoneのSafariでは、センサーへのアクセス許可を求めるダイアログが表示されるので許可します。
(Androidではこの確認は不要らしいですが持ってないので未確認です。。。)
アクセスの許可をすると、画面の上部に表示している、alpha,beta,gamma の値が変わるようになりました。アクセス成功です。
意図通りに値が取れているか確認してみましょう。
スマートフォンを立ててみると、beta の値が90度に近づいていきました。
次にスマートフォンを横向きに傾けてみます。
gamma の値が-90度に近づいていきました。
画面の傾きを検出出来ていることが確認できましたね。
最後に
ジャイロセンサーの傾きの値にアクセスする方法について記載しました。
次回は、傾きによってボールを操作してみようと思います。
ここまでのPlaygroundに記載したソースは以下です。
const createScene = function () {
const scene = new BABYLON.Scene(engine);
const camera = new BABYLON.FreeCamera("camera", new BABYLON.Vector3(0, 0, -1), scene);
camera.setTarget(BABYLON.Vector3.Zero());
// GUI設定
const advancedTexture = BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI("UI");
// 開始ボタンを作成
const btnStart = BABYLON.GUI.Button.CreateSimpleButton("btnStart", "センサー読み取り開始");
btnStart.width = "600px"; // ボタンの幅
btnStart.height = "80px"; // ボタンの高さ
btnStart.color = "white"; // テキストの色
btnStart.fontSize = "24px"; // フォントサイズ
btnStart.background = "green"; // ボタンの背景色
btnStart.cornerRadius = 10; // 角の丸み
btnStart.horizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_CENTER;
btnStart.verticalAlignment = BABYLON.GUI.Control.VERTICAL_ALIGNMENT_BOTTOM;
btnStart.onPointerClickObservable.add(() => {
// ボタンクリック センサーイベント登録
init();
});
advancedTexture.addControl(btnStart); //ボタンを追加
// 表示用パネルの作成
const pnlInfo = new BABYLON.GUI.StackPanel();
pnlInfo.verticalAlignment = BABYLON.GUI.Control.VERTICAL_ALIGNMENT_TOP;
pnlInfo.horizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_CENTER;
pnlInfo.background = "rgba(0, 0, 0, 1.0)";
pnlInfo.width = "300px";
advancedTexture.addControl(pnlInfo);
const createTextBlock = (name, text) => {
const textBlock = new BABYLON.GUI.TextBlock();
textBlock.name = name;
textBlock.text = text;
textBlock.color = "white";
textBlock.fontSize = 24;
textBlock.height = "32px";
pnlInfo.addControl(textBlock);
return textBlock;
};
//表示用のText領域を生成
const alphaText = createTextBlock("alpha", "Alpha: 0°");
const betaText = createTextBlock("beta", "Beta: 0°");
const gammaText = createTextBlock("gamma", "Gamma: 0°");
const init = async () => {
//DeviceOrientationEventを登録
try {
if (typeof DeviceOrientationEvent.requestPermission === 'function') {
await DeviceOrientationEvent.requestPermission();
}
window.addEventListener('deviceorientation', handleOrientation);
} catch (error) {
console.log(' permission denied');
}
};
//センサーの値を表示する
const handleOrientation = (event) => {
const alpha = (event.alpha || 0);
const beta = (event.beta || 0) ;
const gamma = (event.gamma || 0) ;
alphaText.text = `alpha: ${alpha.toFixed(2)}°`;
betaText.text = `beta: ${beta.toFixed(2)}°`;
gammaText.text = `gamma: ${gamma.toFixed(2)}°`;
};
window.addEventListener("resize", () => {
engine.resize();
shaderMaterial.setVector2("resolution", new BABYLON.Vector2(window.innerWidth, window.innerHeight));
});
return scene;
};