豆腐とコンソメ

豆腐とコンソメ

もろもろのプログラム勉強記録

RaspBerryPiでラジコンをつくる(12):もう少しブラウザから操作する

以前、ブラウザからキー入力した情報をsocket.ioを使用してFlaskで作成したWebサーバーに送信する、というところまでやりました。

tohutokonsome.hatenablog.com

ラジコンとしては、最低限の機能を有しているわけですが、もうすこし画面に凝ってみたい、スマホからの操作も意識してみたい、というところもありまして、画面を作成することにしました。

このブログを始めた当初に、日めくりカレンダーを作ってみよう、という中途半端なもの作成した際に、HTMLとCSSの勉強を少ししたのですが、もう忘れてしまっていました。

tohutokonsome.hatenablog.com

あまり作業メモを取っておらず後悔しましたので、今回はちゃんとメモっておこうと思います。

全般的に役に立つ内容はほとんどなく、自分のメモという側面が大きいです。
(あれ、このブログで役に立つことなんてあったけ?)

使用したHTMLエディタ

node.jsの時にはWebStromを使っていたので、こちらを使いたかったのですがお試し期間が終わっちゃいました。
ライセンスを購入したいところなんですが、とり急ぎVsCodeで作業することにしました。

VsCodeのプラグインはこちらを参考させていただきました。
qiita.com


さっそく作成する

とりあえず、socket.ioやらなんやらは忘れて、純粋にhtmlとcssのみ使っていきます。

Bootstrap公式のテンプレートをとってくるところからやろうと思ったのですが、わかりやすい記事がありましたので、以下を参考にしました。

Bootstrap3.x.で何かやるときの最低限のメモ - Qiita

ただ、今回使用するBootstrapのバージョンは4.xにしました。

とりあえず最初にグリッド

参考記事をそのまま真似ています。

てきとうなhtml

<!DOCTYPE html>
<html lang="ja">
  <title>LegoCarコントローラ</title>
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous">
  </head>
  <body>


<div class="container">
    <!-- header -->
    <div class="row">
    <div id="header" style="background-color:#ff0000">header</div>
    </div>

    <!-- content -->
    <div class="row" style="background-color:#00ff00">
        <div class="col-md-3">left</div>
        <div class="col-md-6">center</div>
        <div class="col-md-3">right</div>
    </div>

    <!-- footer -->
    <div class="row">
    <div id="header" style="background-color:#0000ff">footer</div>
    </div>
</div>

    <!-- jQuery first, then Tether, then Bootstrap JS. -->
    <script src="https://code.jquery.com/jquery-3.1.1.slim.min.js" integrity="sha384-A7FZj7v+d/sdmMqp/nOQwliLvUsJfDHW+k9Omg/a/EheAdgtzNs3hpfag6Ed950n" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" crossorigin="anonymous"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js" integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn" crossorigin="anonymous"></script>
  </body>
</html>


ブラウザでみた場合
f:id:konoemario:20170726111013p:plain:w500

参考記事のBootstrap3.xでは、上記でいい感じに幅が揃っていたのですが。headerとfooterがはみ出てしまいました。
どうもBootstrap4.0の影響っぽいです。

選択肢として、カラムの値を12にすればできたけれども、違和感があります。

    <!-- header -->
    <div class="row">
           <div class="col-md-12" style="background-color:#ff0000">header</div>
    </div>

今回、全体をcontainerで囲む必要性を感じなかったので、メインコンテツ部分のみをcontainerで囲むことにしました。

てきとうなhtml(抜粋)

    <!-- header -->
    <div id="header" style="background-color:#ff0000">header</div>

    <div class="container">
        <!-- content -->
        <div class="row" style="background-color:#00ff00">
            <div class="col-md-3">left</div>
            <div class="col-md-6">center</div>
            <div class="col-md-3">right</div>
        </div>
    </div>
        <!-- footer -->
    <div id="header" style="background-color:#0000ff">footer</div>


ブラウザでみた場合
f:id:konoemario:20170727132424p:plain:w500


ヘッダーを編集する

やっぱり、ヘッダーにナビゲーションっぽいものがあるといいのかな、ということでnavbarをつけます。

navbarに関しては、公式のほぼそのままです。

Navbar · Bootstrap

さきほどのheader部分をまるっと以下に置き換えます。

てきとうなhtml(抜粋)

<!-- headerはnaviだよ -->
    <nav class="navbar  navbar-toggleable-md navbar-inverse bg-primary">
      <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
      </button>

      <!--Brandはnavbar-brand -->
      <a class="navbar-brand navbar-inverse" href="#">tohu</a>

      <!--navの要素-->
      <div class="collapse navbar-collapse" id="navbarNav" >
        <ul class="navbar-nav">
          <li class="nav-item">
            <a class="nav-link" href="#">要素1</a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="#">要素2</a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="#">要素3</a>
          </li>
        </ul>
      </div>
    </nav>


ブラウザでみた場合
f:id:konoemario:20170727160354p:plain:w500

せっかくなので、上部に固定します。
navのclassにfixed-topを追加しました。

てきとうなhtml(抜粋)

    <!-- headerはnaviだよ -->
    <nav class="navbar  navbar-toggleable-md navbar-inverse bg-primary fixed-top">
      <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
      </button>

      <!--Brandはnavbar-brand -->
      <a class="navbar-brand navbar-inverse" href="#">tohu</a>

      <!--navの要素-->
      <div class="collapse navbar-collapse" id="navbarNav" >
        <ul class="navbar-nav">
          <li class="nav-item">
            <a class="nav-link" href="#">要素1</a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="#">要素2</a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="#">要素3</a>
          </li>
        </ul>
      </div>
    </nav>

また、例のごとくfixed-topで固定した分、メインコンテンツをnavbarの高さ分paddingします。

どれくらいpaddingしていいかは、公式サンプルを参考にしました。

Fixed top navbar example for Bootstrap

    <style>
        /* Show it is fixed to the top */
        body {
        /*min-heightはスクロール検証用*/
          min-height: 75rem;
          padding-top: 4.5rem;
        }
    </style>


ブラウザでみた場合
f:id:konoemario:20170727160605p:plain:w500

作成する画面イメージ

ここに来て、手がとまっちゃいました。
というのも、どんな感じの画面をつくるのかをあまり考えていなかった!

とりえあえずのイメージをdraw.ioで書いてみました。


作成する画面イメージ
f:id:konoemario:20170727210800j:plain:w500

右側に広大なスペースがありますが、あまったら畑でも耕しておけばいいと思うので、とりあえずこんな感じでいきます。


メインコンテンツ

とりあえずメイン部分となる、カメラの映像の部分と、コントローラーの部分をつくっていきたいと思います。

メインは、カメラ、コントローラ部分と畑部分とで2カラムとしますので、以下のようにしました。

てきとうなhtml(抜粋)

    <div class="container">
        <!-- content -->
        <div class="row" style="background-color:#00ff00">
             <!--カメラとコントローラー-->
            <div class="col-md-9" style="background:red">main</div>
            <!--未開拓地域-->
            <div class="col-md-3" style="background:yellow">side</div>
        </div>
    </div>


ブラウザでみた場合
f:id:konoemario:20170727161728p:plain:w500


カメラ部分

ラズパイのカメラの映像はお馴染みの「mjpg-streamer」を使っています。
なので、ストリミーング映像は、以下のimgタグを使うことで簡単に表示できます。

    <img src="http://ラズパイのIPアドレス:8080/?action=stream">

ストリーミング映像のサイズは、mjpg-streamerのオプションで設定しています。
今は、「240 X 320」で設定しているのでそのサイズを意識することにしました。

てきとうなhtml(抜粋)

            <!--カメラとコントローラー-->
            <div class="col-md-9" style="background:red">
                <div id="monitor-wrapper">
                  <div id="monitor">
                      <!--とりあえず適当な画像を置いておく-->
                      <img src="https://placehold.jp/240x320.png">
                  </div>
                </div>

styleは以下のようにしました。

        #monitor-wrapper{
            padding-left:30px;
        }

        #monitor > img {
            transform: rotate(90deg);
        }

とりあえず、こんな感じになった。


ブラウザでみた場合
f:id:konoemario:20170727213011p:plain:w500

「monitor-wrapper」やらimgタグでrotateしているのはラズパイのカメラの取り付けの際にカメラの向きが90度右になった状態で設置してしまったので、それを補正するために対応した。

自宅のカメラを直せば、こんなことをしなくてよいのだけれども、免許合宿先で作業しているため、仕方がない。

コントローラ部分

ボタンを4つ十字に並べるだけといわれれば、それだけなんだけれども、それだけをどうやってやればいいのかなぁと悩んだ。

結果、flexboxと呼ばれるCSSレイアウトを使うことにした。

coliss.com

とりあえず、以下のように3 X 3のマスの上にButtonを並べるイメージで考えることにして、Button以外の要素は背景色に同化させて見えないようにした。

3X3のマスにボタンがあるイメージ
f:id:konoemario:20170727214246p:plain:w500

てきとうなhtml(抜粋)

            <!--カメラとコントローラー-->
            <div class="col-md-9" style="background:red">
                <!--カメラ-->
                <div id="monitor-wrapper">
                  <div id="monitor">
                      <img src="https://placehold.jp/240x320.png">
                  </div>
                </div>
                <!-- コントローラー-->
                <div id="controller_wrapper">
                    <div class="dummy_button"></div>
                    <button class="controller_button">前進:W</button>
                    <div class="dummy_button"></div>
                    <button class="controller_button">左折:A</button>
                    <div class="dummy_button"></div>
                    <button class="controller_button">右折:D</button>
                    <div class="dummy_button"></div>
                    <button class="controller_button">後退:S</button>
                    <div class="dummy_button"></div>
                </div>

styleは以下とした。

        /*flexさせたい要素の親要素のdisplayとして設定する。*/
        #controller_wrapper{
            background: #42aaf4;
            width:300px;
            height: 150px;
            display: flex;
            flex-direction: row;
            flex-wrap: wrap;
        }

        .controller_button{
            margin: 1%;
            padding: 0;
            width:30%;
            height:30%;
            background: #c97796;
            text-align: center;
            color: white;
            border-radius: 10px;
        }

        .dummy_button{
            margin: 1%;
            padding: 0;
            width:30%;
            height:30%;
        }


ブラウザでみた場合
f:id:konoemario:20170727215055p:plain:w500

申し訳程度にフッターをつける

フッターがあるとそれっぽいかなぁということで、フッターをつけることにした。

Bootstrap公式のフッターをそのままもってくる。

Sticky Footer Template for Bootstrap

てきとうなhtml(抜粋)

    <!-- footer -->
    <footer class="footer">
      <div class="container">
        <p class="text-muted"><a href="http://tohutokonsome.hatenablog.com/archive">豆腐とコンソメ</a></p>
      </div>
    </footer>

スタイルもそのまま。

        /* Sticky footer styles
        -------------------------------------------------- */
        html {
          position: relative;
          min-height: 100%;
        }
        body {
          /* Margin bottom by footer height */
          margin-bottom: 60px;
        }
        .footer {
          position: absolute;
          bottom: 0;
          width: 100%;
          /* Set the fixed height of the footer here */
          height: 60px;
          background-color: #f5f5f5;
        }


ブラウザでみた場合
f:id:konoemario:20170728175930p:plain:w500

なかなかひどいデザインです。 もう動かしたい!という気持ちがでてきちゃっているので、先に使えるようしてからデザインを整えたいなぁと思っとります。

次回は、これをnode.jsのプロジェクトにのっけていきます。