4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Babylon.jsAdvent Calendar 2024

Day 15

Webブラウザで玉転がしを作成してみる(1)

Posted at

はじめに

この記事は Babylon.js Advent Calendar 2024  
の、15日目の記事です

何度かに分けて、スマホのセンサーにアクセスして玉転がしをするページを作成してみます。

今回の内容。

スマートフォンには、デバイスの動きや向きを検知する ジャイロセンサー加速度センサー が搭載されており、これらのセンサーの値はブラウザからでもアクセスすることができます。
その値を画面に表示する方法についてまとめました。

デバイスのセンサー類にアクセスする

まずはジャイロセンサーにアクセスしてみます。

DeviceOrientationEvent が、デバイスの方向の情報を取得するイベントです。方向が変更されるたびにイベントが発火し、以下の情報を取得できます。
1.alpha(スマホの回転)
2.beta(スマホの上下の傾き)
3.gamma(スマホの左右の傾き)
図にすると以下のようになります。

image.png

では、ジャイロセンサーにアクセスしてみましょう。
ジャイロセンサーにアクセスするため、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度に近づいていきました。
image.png

次にスマートフォンを横向きに傾けてみます。
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;
};
4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?