ESP32のwebサーバをデザインする

前回ESP32でWebサーバを立て、そこからサーボモータを制御するみたいなことをしました。

心残りは、ちょっと画面デザインが貧相だったという点です。

最近、WordPressに浸かりきっていて、自分でhtmlを編集するってことがあまりありません。

が、そんなんでも、BootstrapとかMaterializeとかの無料のフレームワークを使っていけば、ページのデザインをそれなりにつくりこめます。

最新のデザインでキレキレに!とまではいかないですが。下のようにホームページ感をだしたサンプルをつくってみました。

https://tekuteku-embedded.xyz/wp-content/uploads/2020/11/ESP32_WR_Boostrap.html

See the Pen
bootstrap
by Michinori Takeuuchi (@michi1982)
on CodePen.

WEBページの作成方法については、詳しく説明されてるサイトがそれこそ無限にあるので、そこで、順をおって、丁寧に勉強するのが一番かと思います。

はっきり言って、htmlなんて勉強する気はさらさらないんだけど、今回の記事のようなページを作るためには、どうすればいいか?雑につかみたいって感じの人のためにまとめてみました。

上のページのソースコードがざざっと分かるようになるのが目標です。なので、一記事で、html,css,java scriptまでサラリとまとめるつもりです。(不可能に挑戦)

WEBページはhtmlとCSSとjsで作られてる

WEBページを作るときは、htmlファイルというのをベースにページの骨格をつくり、cssで、文字とか画像とかのスタイルを決め、js(java script)でボタンをクリックしたときの動作などの処理を決めてます。骨格・スタイル・動作です。

外部ファイルでこれらの三つを別々に記述することもできますが、htmlファイルにみんなまとめて書くこともできます。今回は後者です。

html エディターを用意する

htmlファイルを書くには専用のエディタで書いた方がいいです。自分はatomを使ってますので、紹介しときます。

A hackable text editor for the 21st Century

Great things happen when developers work together-from teaching and sharing knowledge to building better software. Teletype for Atom makes collaborating on code just as easy as it is to code alone, right from your editor. Share your workspace and edit code together in real time.

htmlの1文の書き方

下のように1文の構成は、<記号>hoge</記号>です。記号の部分で表示されるものが変わります。これをタグっていいます。記号によっては、終了タグ</記号>が不要なのもあります。

例えば、<p>hoge</p>のpは段落。<h1>hoge</h1>のh1は見出しを書くよ!っていう意味のタグです。実際に下の用にコードを書くと、なんで勝手にフォントサイズが変わるの?と思うかもしれません。これは、デフォルトでpとh1のフォントサイズが決まってるからです。

See the Pen
<h><p>
by Michinori Takeuuchi (@michi1982)
on CodePen.

h1の見出しですが、h1~6まであります。数字を大きくするとフォントサイズも小さくなってきます。

See the Pen
eYzYogE
by Michinori Takeuuchi (@michi1982)
on CodePen.

htmlファイル構成

ファイル構成は下の通りです。細かいことはおいといて、ファイル全体は<head>~~~</head>と<body>~~~</body>の二つにわかれます。

headはCコードでいうヘッダーで、bodyはメイン関数みたいな役割です。書くべきところは下のハイライトの部分です。

画像とか文章とかはbodyタグ内に書いて、なんか関数をつくって、処理をしたいときはscriptのタグ内にかいて、デザイン変えたいときはstyleタグ内でいじくるって感じになります。

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
  <style>
    <!--ここにCSSの内容を書く-->
  </style>
  </head>
  
  <body>
    <!--ここにページの内容を書く-->

  <script>
    <!--ここにjava script-->
  </script>
  </body>
</html>

なので、これをテンプレとして、自分のページを作っていけばよいです。他の意味不明な記述はページの言語設定や画面表示の設定などをしてるとこですが、スルーします。

CSSの使い方は3つある

cssには使い方が三つあります。

  1. html内にリンクだけ指定して外部ファイルで定義する ( ***.cssで定義)
  2. 個別のタグ内で直接定義する方法
  3. headタグ内にあるstyleタグに定義する方法

2でやる場合はこんな感じです。

See the Pen
style
by Michinori Takeuuchi (@michi1982)
on CodePen.

それぞれのタグには属性というのを持っていて、例えば、文字サイズならfont-size、文字色の設定ならcolorという属性です。

CSSは、その属性の値を目的のデザインに合わせて変更していく役割があります。

タグ内で直接指示する方法では、style=” 属性名:設定したい値 “とします。これで、そのタグのスタイルを直接カスタマイズすることができます。上の例がそうです。

ただ、似たようなタグがいっぱいできてくるといちいちこんな感じで個別に設定すると面倒な気がしてきます。

そういう場合は3の方法をつかいます。

3は、スタイルタグで定義する方法です。下のCSSをクリックするとp{…}という記述があります。先頭のpはpタグのデザインを一括で設定しますっていう宣言みたいなもんです。セレクターといいます。

See the Pen
style2
by Michinori Takeuuchi (@michi1982)
on CodePen.

pタグの設定がcssで一括で決めることができてますね。ただ、どんなタグがあって、それには、どんなプロパティがあるのか?知っとかないとできません。参考サイトで検索しましょう。

参考サイト

一番詳しいのは、ここ。Mozillaの公式サイト

MDN WEB DOCS

JavaScriptやCSS、HTMLのほか、さまざまなWeb APIに関するウェブ開発者向けの情報やチュートリアルがあります。最近、googleとかマイクロソフトとかもこのサイトに情報を集約させようみたいな動きがあるとかないとか。

でも、これ難しいって人は、下のサイトがおすすめです。副業ブームのせいか、htmlの説明サイトって、アフィリエイト系が多くて、雑情報が多いなかで、このサイトは、シンプルな構成で見やすいす。

HTMLクイックリファレンス

classの使い方

さっき、pタグのデザインをsytleタグで一括設定しましたが、このpタグだけは、色を変えときたいということがあると思います。その時はclassというのをつかいます。

See the Pen
class
by Michinori Takeuuchi (@michi1982)
on CodePen.

class名を指定して、プロパティを編集する場合は、.クラス名{…}とすればいいです。CSSのセレクタは、指定方法が色々あり、今回のタグやクラス名で指定する方法の他にも、IDやタグのnameで指定できたりします。

div と span

あとソースコードで使われてるのにdivとspanがあります。divから説明します。というかdivはそれ自体では、何もしないですが、よくでてきます。

See the Pen
div
by Michinori Takeuuchi (@michi1982)
on CodePen.

pタグで文章書いているのと何も変わらないです。ただ、class名をつけると下のように威力を発揮します。

See the Pen
div_class
by Michinori Takeuuchi (@michi1982)
on CodePen.

divタグ内のタグの文字色を一括でかえられました。便利す。

次にspanは?というとdivに似た使われ方をしますが、これは改行しません。どういうことかというと。

See the Pen
div_kaigyo
by Michinori Takeuuchi (@michi1982)
on CodePen.

こころの所だけ赤にしたかったんですが、改行され失敗しました。そんな時にSPANを使うんです。

See the Pen
span_kaigyo
by Michinori Takeuuchi (@michi1982)
on CodePen.

Tableの出し方

サンプルページはテーブルも出してましたので、紹介します。

See the Pen
zYBxZba
by Michinori Takeuuchi (@michi1982)
on CodePen.

<tr>と<td>を組み合わせて、表をつくっていきます。<tr>が行で<td>が要素になります。まぁ見た通りです。

.tab{border: 1px solid;}で外枠の線を決めています。

.tab td{border: 1px solid gray;}で内側の格子線を決めてますが、ここは説明してませんでした。セレクタをクラス名 tdとすると、クラスに設定したタグの子要素のタグ(ここではtd)を指定することができます。

つまり表の各セルのボーダを指示することで、格子を書いている訳です。

Radioボタンの使い方

ページはラジオボタンもつかっていました。

See the Pen
radio
by Michinori Takeuuchi (@michi1982)
on CodePen.

ラジオとかボタンとかスライダとかコントロールする系のUIはinputタグで設定します。typeというプロパティに使いたいコントローラを指示します。今回はラジオなのでtype=”radio”になります。

ラジオボタンのよこにテキストを配置するので、labelタグとセットで使います。labelはこんな感じで何かの入力フォームとセットでつかいます。

ボタンの使い方

当然 type=”button”でボタンもつくれます。

See the Pen
input_button
by Michinori Takeuuchi (@michi1982)
on CodePen.

別のボタンの作り方

ボタンの場合は、別にbuttonタグというのもあって、今回はそっちをつかってます。inputタグのボタンの機能拡張版で図とテキストを組み合わせたりできますね。

See the Pen
button
by Michinori Takeuuchi (@michi1982)
on CodePen.

Bootstrapの導入の仕方

これまでで、今回実装した機能のタグはほぼ網羅しました。これでもソースがいまいち読めないの所は、おそらくscriptの部分と、bootstrapの機能を使っている部分だとおもいます。

まず、bootstrapを使うために設定をしましょう。といってもリンク貼るだけですが。localにファイルを保存する方法とネット経由でファイルにアクセスする方法(CDN)がありますが、今回は後者を採用します。

headタグにbootstrap用のcssのリンク、jQueryというjava scriptのライブラリのリンク、boostrap用のjava scriptのライブラリのリンクを設定します。

とりあえず、公式サイトにあるスタータテンプレートというやつをコピペです。

<!doctype html>
<html lang="ja">
  <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://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">

    <title>Hello, world!</title>
  </head>
  <body>
    <h1>Hello, world!</h1>

    <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js" integrity="sha384-wHAiFfRlMFy6i5SRaxvfOCifBUQy1xHdJ/yoi7FRNXMRBu5WHdZYu1hA6ZOblgut" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k" crossorigin="anonymous"></script>
  </body>
</html>

Bootstrapの基本的な使い方

bootstrapはcssで各コンポーネント毎に独自のクラス名がついたテンプレートが用意されていて、それを流用していくだけで、おしゃれなデザインにしてくことができます。

下に公式サイトのリンクを貼っておきます。ここから、使いたいコンポ―ネントを選び、ソースに貼り付けていくだけ…。

Bootstrap

世界で最も人気のあるフロントエンドフレームワーク

例えば、ボタンは “btn btn-*****”というクラス名でテンプレがあり、それを呼ぶだけで、下の用なノーマルよりだいぶマシなボタンを召喚できます。

See the Pen
bootstrap
by Michinori Takeuuchi (@michi1982)
on CodePen.

bootstrapでタブ切り替えページをつくる

今回のデザインで一番難しいところは、タブによる切り替えページです。まず、bootstrapを使わない方法を説明して、あ!めんどくさ!ってところを感じたいと思います。

bootstrapを使わないでタブ機能を作ったのがこれです。

See the Pen
nobootstrap_tab
by Michinori Takeuuchi (@michi1982)
on CodePen.

上のコードからCSSの設定を除いてみます。

See the Pen nobootstrap_tab_onlyhtml by Michinori Takeuuchi (@michi1982) on CodePen.

元々はラジオボタンだということが分かりました。

<input type="radio" name="tab_item" id="tab1"   class="tab_radio" >
<label for="tab1" class="tab_menu"> tab1</label>

設定は上で説明したとおりのラジオボタンの設定です。

ラジオボタンの下に各ボタンクリック時に表示したい内容が書いてあります。ここでidという属性がありますが、タグにつけるIDです。classと似てますがidは他のタグに同じidはつけられません。あとでcssの設定でこれを使います。

<div id="tab1_cont" class="tab_contains">
  <p>タブ1選択中</p>
</div>

このhtmlをベースにcssがやるべきことは

1) ラジオボタンは消す

2) 選択したタブの色を変更する

3) 本文が全部でてしまってるので取り合えず消す

4) そのうえでタブを選択したところだけ表示する

です。

それぞれ説明してきます。まずラジオボタン消すには

.tab_radio{
 display:none;
}

プロパティdisplayをnoneにすれば、ラジオのお豆●っぽいのは消えます。

次にクリックしたら、ラベルの背景を青にするには、

.tab_radio:checked + .tab_menu{
  background-color:skyblue;
}

このセレクタの設定はテクニカルですが、.tab_radio:checkedという書き方で、tab_radioクラスという名前のラジオボタンが選択されます。その後で+.tab_menuと続きますが、これは隣接セレクタと言って、隣り合うタグ、ここではクリックされたラジオボタンの隣りあうタグつまりクリックされたラジオボタンのラベルが選択されます。

そして、その背景色を青にしてます。

.tab_containsは本文の内容を表示するタグですが、display:noneでとりあえず全消ししてます。

.tab_contains{
  margin-top:-1px;
  display:none;
}

最後にクリックしたときだけ本文表示する処理ですが、#tab1:checkedでクリックしたラジオボタンを選択します。tag1は上で説明したIDです。

これまでクラスをセレクタで選択するには .クラス名でいけましたが、別の方法として、タグにつけたIDをセレクタで選択することもできて、それには、 #ID名とします。

その後にまた #tab1_contとあります。#tab1_contは本文の内容を表示しているdivタグのIDです。その間に~という謎記号がありますが、これは間接セレクタといいます。

意味合い的にはtab1というIDをもったラジオボタンがクリックされたら、tab1_contというIDをもったタグを選択するといった感じです。そして、選択されたものdisplay:blockにして、本文を表示してます。

#tab1:checked ~ #tab1_cont,
#tab2:checked ~ #tab2_cont,
#tab3:checked ~ #tab3_cont{
  display:block;
}

色々設定に必要な箇所が多くて大変ですね。そこで、bootstrapを使うとこうなります。cssがなくなり、すっきりしました。

See the Pen
bootstrap_tab
by Michinori Takeuuchi (@michi1982)
on CodePen.

タブの切り替えは箇条書きするときに使うulタグとuiタグベースで書かれています。

基本的には上でやったタブクリック時の動作は全部bootstrapが裏側でいい感じにしてくれて、複雑なCSSは一切ありません

ユーザがやるべきことは、このタブ機能が実装されているタグのクラス名を調べるだけ。それをhtml上でよびだせば、簡単に実装できるって訳です。

どうやって、機能をさがしだせばいい? チートシートが便利です。

チートシートを使う

リンクは下。海外のサイトですが、bootstrapの典型的なモジュールが集められているので、スーパー便利です。動作みて、気に入ったらコピペで使う。これがbootstrapの正しい使い方?

https://hackerthemes.com/bootstrap-cheatsheet/

Gridシステム

Webページを開いたデバイスによって、画面レイアウトを変更する機能がbootstrapに実装されてます。例えば、下のgifのようにウィンドウサイズを変更すると、ページのコンテンツが見切れないように勝手に変更されてます。レスポンシブというやつです。

今回は使ってませんが、bootstrapの主要機能なので、作り方だけ簡単に紹介しときます。

上の例は、ページに合計12個のコンテンツがあって、行毎に

Windowsサイズ大のとき:(1,2)-(3,4)-(5,6,7,8)-(9,10,11,12)

Windowsサイズ中のとき:(1)-(2)-(3)-(4)-(5,6)-(7,8)-(9,10)-(11,12)

Windowsサイズ小のとき: (1)-(2)-(3)-(4)-…-(9)-(10)-(11)-(12)

という感じでコンテンツの表示構成が変化していっています。細かい話は置いといて、下記のサイトを使えば、直観的にグリッドの設定ができるので、便利です。

Shoelace – Visual Bootstrap 3 Grid Builder

The only visual Bootstrap 3 grid builder featuring full responsive media query views and fully functional preview.

サイトにいくと、下のような画面が出てきます。左側にDesktopとかTabletとかPhoneとかディスプレイのサイズに応じたデバイス名が表示されています。

設定したいデバイスに反映させたいグリッドを真ん中の画面でマウスをドラッグしながら、領域に分けてきます。下は、上のgifの例と同じようなグリッド割りをした場合です。

すると右側のWindowに対応するhtmlのコードが出力されるので、これを実際のコードに反映するだけです。ただ、このままだと、tabletとphoneはシングルカラムになってしまうので、tabletのグリッド割りをすこし変更します。

こんな感じ。最終的に生成されたコードは下。超簡単にレスポンシブを実現できました。あとはdivタグ内にそれぞれ、中身を書いていけばいいわけです。

<div class="row">
    <div class="col-md-6">ここに中身を書く</div>
    <div class="col-md-6">ここに中身を書く</div>
</div>
<div class="row">
    <div class="col-md-6">ここに中身を書く</div>
    <div class="col-md-6">ここに中身を書く</div>
</div>
<div class="row">
    <div class="col-sm-6 col-md-3">ここに中身を書く</div>
    <div class="col-sm-6 col-md-3">ここに中身を書く</div>
    <div class="col-sm-6 col-md-3">ここに中身を書く</div>
    <div class="col-sm-6 col-md-3">ここに中身を書く</div>
</div>
<div class="row">
    <div class="col-sm-6 col-md-3">ここに中身を書く</div>
    <div class="col-sm-6 col-md-3">ここに中身を書く</div>
    <div class="col-sm-6 col-md-3">ここに中身を書く</div>
    <div class="col-sm-6 col-md-3">ここに中身を書く</div>
</div>

JavaScriptでラジオボタンをクリックしたときの処理を記述する

これまでの説明で、デザイン的なところはある程度網羅しましたが、デモだとラジオボタンをクリックするとボタン毎に対応したサーボモータの目標角度が下のラベルに表示されてます。

↑はピカチューボタンを押した時の動作例です。Target Angleが180degになってます。

このボタンを押した時の処理はjava scriptで記述されます。今回のデモコードをみると<script>….</script>で囲われてる部分がjava scriptになります。

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>tr1</title>

    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
    <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
  </head>
  <body>
  <script>
      ここにjava scriptをかく
  </script>
  </body>
</html>

機能を実現するのは何パターンかあるので、実際にやってみました。まずは、最初の方法。

See the Pen
radio
by Michinori Takeuuchi (@michi1982)
on CodePen.

ラジオボタンのname属性におなじ名前をつけて、onchangeというイベントが発生したら、func_radioという関数呼ぶよ、みたいに定義しときます。

<input type="radio" name="mode" value="fs" onchange="func_radio()" autocomplete="off">

次に下のように、getElementsByNameという関数をつかって、modeって名前のついたラジオボタンのオブジェクトをごっそりelemというパラメータに取得します。

  var elem = document.getElementsByName("mode");

ラジオボタンの数だけ、elemに配列として、オブジェクトがぶら下がるので、下のようにfor文で、checkされているラジオボタンを発見しようという仕組みになってます。

  function func_radio(){
    for(var i =0;i<elem.length;i++)
    {
      if (elem[0].checked)
      {
          servoP.innerHTML = 180;
      }
      if (elem[1].checked)
      {
          servoP.innerHTML = 0;
      }
      if (elem[2].checked)
      {
          servoP.innerHTML = 90;
      }

ラベルにサーボの目標開度が表示する方法についてですが、これは、spanタグにidをつけといて、(この段階では、なんの数値も表示していない)

<div class="angle" style="text-indent: 5em; "><font size = "7"><span id="servoPos"></span></font>deg</div>

getElementByIdという関数で、スパンタグのオブジェクトをservoPの変数に格納します。

var servoP = document.getElementById("servoPos");

そいで、innerHTMLというプロパティに数値をいれれば、spanタグ内に数値が表示できます。

servoP.innerHTML = 180;

JavaScriptでラジオボタンをクリックしたときの処理を記述する(jQuery版)

それでは、jQueryを使った違う方法でもやってみます。jQueryとは、java scriptのライブラリで、使えば、DOM操作を簡単に実現できるというものです。今回のコードはこれを使ってます。

デモコードの<head>タグに以下の一行がありましたが、これで、jQueryを使うことができます。

<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>

jQueryのラジオボタンの処理は下のような感じです。

See the Pen
radio_jquery
by Michinori Takeuuchi (@michi1982)
on CodePen.

下がjQueryで書いたコードを抜き出したものです。

$(function(){
     $( 'input[name="mode"]:radio' ).change( function() {
        var sel = $(this).val();
        if(sel == "pk")
        {
          servoP.innerHTML = 180;
        }
        if(sel == "fs")
        {
          servoP.innerHTML = 0;
        }
        if(sel == "fr")
        {
          servoP.innerHTML = 90;
        }
     });
  });

頻出してる$マークですが、これはjQuery()と同じ意味で、jQueryのライブラリを呼び出す関数になります。実際には、$(セレクタ).(メソッド)みたいな組み合わせで使っていきます。$がきたら、あ、jQuery使ってるなと思えばいいと思います。

$( 'input[name="mode"]:radio' ).change( function(){関数の中身});

上のコードの例では、’input[name=”mode”]:radio’がセレクタで、これでmodeという名前のついたラジオボタンが一括で、選択されます。その後のchangeは通常のjsと同じで、ラジオボタンの状態が変化すると発生するイベントで、発火した時は()の中のfunction(){}の処理がはしるという形になっています。

セレクタで制御したいDOMを指定して、ドット以下にjQueryで用意されているメソッドを指定して、DOMの操作内容を決めるみたいな流れで、記述してくようです。

ちなみに一番最初にある

$(function(){ 

});

ですが、これはhtmlがロードされるまで、関数の実行を待つという意味があり、jQueryを使うときは、必ずこれを宣言しときます。

以上です。

これまでで、今回のサンプルコードの中身の大体説明できました。かなりざっくりですが、後は個別に調べて、ずんずん深堀りしていけば、作りたいページを作っていけるはずです。

Webページのデザインについては、これで終了ですが、一点重要な箇所を残してます。

それは、ラジオボタンで決めたサーボモータの目標角度をどうやって、ESP32に知らせてるか?ということです。

今回のサンプルコードでは、Ajax通信のGETメソッドで、こんな感じで実現してるのですが

    $.ajaxSetup({timeout:1000});
    function servo(pos) {
      $.get("/?value=" + pos + "&"); //posがESP32にAjax通信で値がわたされる
      {Connection: close};
    }

マイコンを制御する上で重要な箇所なので、これは別記事で取り上げていきます。とりあえず、今回は、ここら辺で何かしてるっぽいにとどめておきます。

以上です。かなりの上澄みのすくいっぷりでしたが、一応、説明は網羅できました。

htmlはきらいだ、でもjava scryptはバンザイ 🙂

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です