2
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?

More than 1 year has passed since last update.

ローカルサーバでスマートフォンブラウザから端末の向きを検出する

Posted at

結論から

httpsサーバじゃないといけない

カメラを利用するのにも必要だったので、以前の記事を参考に

$ openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout key.pem -out cert.pem

で、鍵作ったあと

$ http-server -S -C cert.pem

or

server.js
const fs = require('fs')
const express = require('express');
const app = express();
const https = require('https');
const options = {
  key:  fs.readFileSync('./key.pem'),
  cert: fs.readFileSync('./cert.pem')
};
const server = https.createServer(options, app);
const PORT = process.env.PORT || 3000;

// ルート
app.get('/' , function(req, res){
    res.sendFile(__dirname+'/public/index.html');
});

// サーバの立ち上げ
server.listen(PORT, () => {
  console.log('listening on https://localhost:' + PORT);
});

動作した環境

  • iOS15.6.1(iPhone8)
    • safari
    • chrome
  • Android12(Pixel 6a)
    • chrome
  • Node.js v16.15.1
    • express v4.18.1

スマートフォンブラウザで向き取得するための参考サイト

ここらへんだけを見るとすぐ使えそうに思えたけども、コードコピペしてもローカルサーバだとこんなエラー

IMG_3488.PNG

CodePenやOpenProcessingなんかだとうまくいく

あと、Netlifyにアップしたらうまくできたし、たぶんGitHub pagesでもできると思う

が、今回動作させたい環境でインターネット使えるか怪しかったので、ローカルサーバで動作させてみたかった

注意点

ローカルサーバ関係ないが、スマフォの向き情報を取得するための許可をもらうための処理の

//. ユーザーに「許可」を求めるダイアログを表示
          DeviceOrientationEvent.requestPermission().then(function (response) {
            if (response === 'granted') {
              // 許可
            }
          }).catch(function (e) {
            alert(e);
            console.error(e);
          });

この処理は、ボタンクリックした後に処理します

サンプルコード集

p5jsを使って画面に傾きをテキスト表示

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>スマフォ向き取得テスト</title>
</head>

<body>

  <button id="btn">クリック</button>

  <ul>
    <li id="rx"></li>
    <li id="ry"></li>
    <li id="rz"></li>
  </ul>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.2/p5.min.js"></script>
  <script>
    function setup() {
      frameRate(10);

      select('#btn').mousePressed(() => {
        if (window.DeviceOrientationEvent) {
          //. ユーザーに「許可」を求めるダイアログを表示
          DeviceOrientationEvent.requestPermission().then(function (response) {
            if (response === 'granted') {
              // 許可
              select('#btn').hide();
            }
          }).catch(function (e) {
            alert(e);
            console.error(e);
          });
        }
      });
    }

    function draw() {
      const rx = round(rotationX * 100) / 100;
      const ry = round(rotationY * 100) / 100;
      const rz = round(rotationZ * 100) / 100;
      select('#rx').html(rx);
      select('#ry').html(ry);
      select('#rz').html(rz);
    }

  </script>
</body>

</html>

p5jsだと許可もらったあとは rotationX で扱えます

その他は、こちら

socket.ioでサーバに共有

サーバ側(Node.js)

npm i socket.io express
const fs = require('fs')
const express = require('express');
const app = express();
const path = require('path');
const https = require('https');
const options = {
  key:  fs.readFileSync('./key.pem'),
  cert: fs.readFileSync('./cert.pem')
};
const server = https.createServer(options, app);
const io = require('socket.io')(server);
const PORT = process.env.PORT || 3000;

// app.get('/', express.static(path.join(__dirname, '/public/index.html')));
app.get('/' , function(req, res){
    res.sendFile(__dirname+'/public/index.html');
});
// app.use('/public', express.static(path.join(__dirname, '/public')));

io.on('connection',function(socket){
    socket.on('rotation',function(rot){
        console.log('rx:' + rot.x + ',  ry:'+rot.y+',  rz:'+rot.z);
    });
});

// サーバの立ち上げ
server.listen(PORT, () => {
  console.log('listening on https://localhost:' + PORT);
});

クライアント側(html,js)

index.html
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style>
    html, body {
      margin: 0;
      padding: 0;
    }
    canvas {
      display: block;
    }
  </style>
  <title>スマフォ向き取得テスト</title>
</head>

<body>
  <script src="/socket.io/socket.io.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.2/p5.min.js"></script>
  <script>
    const socket = io();

    let rots = {};
    let textArea;

    function setup() {
      if (DeviceOrientationEvent && DeviceOrientationEvent.requestPermission) {
        const btn = createButton('クリックして許可', () => {
          //. ユーザーに「許可」を求めるダイアログを表示
          DeviceOrientationEvent.requestPermission().then(function (response) {
            if (response === 'granted') {
              // 許可
              btn.hide();
            }
          }).catch(function (e) {
            alert(e);
            console.error(e);
          });
        });
      }

      // createCanvas(windowWidth, windowHeight);
      textArea = createElement('textArea');
      textArea.position(10, 10);
      textArea.style('width:95%;height:95vh');

      socket.on('rotation', (rot) => {
        // console.log(rot);
        rots[rot.id] = rot;
      });
    }

    function draw() {
      textArea.html(JSON.stringify(rots, null, ' '));
    }

    function deviceMoved() {
      const rx = round(rotationX * 100) / 100;
      const ry = round(rotationY * 100) / 100;
      const rz = round(rotationZ * 100) / 100;
      socket.emit('rotation', {
        x: rx,
        y: ry,
        z: rz
      });
    }

  </script>
</body>

</html>

p5jsだと、デバイス端末が動いたときだけ送るってこともできます

2
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
2
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?