platonのブログ

思考の整理とアウトプット、たまにグラブル

iPadに電卓が無いなら自分で作ればいいじゃない

手っ取り早く電卓を使いたい方へ

platon-index.github.io
上記サイトをSafariで開き、右上のビックリ箱みたいなボタンを押して「ホーム画面に追加」を押してください。
電卓アプリのように使用できると思います。

はじめに

私事ですが、最近新発売のiPad(第8世代)を購入しました。
価格がiPadのなかでは安く、性能もそこそこのコスパ機種という評判を聞き、ムフフな動画鑑賞のため日経新聞の紙面を読むために買いました。

Apple製品は以前ラブライブの音ゲー専用機としてiPod touchを使ったことはあったものの、それ以外ではWindows・Androidばかりだったため基本的なこともわからぬままiOSの海に飛び込むことに。

実際に操作したところ、非常にサクサク動くことに驚きました。
Apple Pencilのパチモンでお絵描きもしてみましたが、想像以上にスムーズに書くことができ、クリエイター向けの端末のような印象を受けました。
ゲームもなめらかに動き、場合によってはPCよりも動作が速い可能性すら感じます。


しかし、そんなiPadに思わぬ盲点がありました。
それは「電卓が無い」ということです。
どうもジョブズがデザインに満足せず、iPadには標準アプリとして搭載しなかったとの噂だそうです。

「デザインは何でもいいから電卓が使いたい!」と思ったので、アプリを探してみるも無料版は広告付きのものばかり。
個人的にはPCの電卓は入力がしにくく、スマホとは独立した計算機がほしいと思っていたので困りました。


その時、私の中のマリー・アントワネットがこう言いました。
「iPadに電卓が無いなら自分で作ればいいじゃない」

f:id:Platon:20160514191241j:plain
マルティン・ファン・マイテンス「マリー・アントワネット」

王妃の声に押され早速iOS向けのアプリ開発について調べたところ、Appleプラットフォームでの開発にはMacが必要とのこと。
この時点で、まともな開発はできないということがわかりました。

ではどうすればいいか。
とりあえず、web上で動く計算機を作ることでお茶を濁すことにします。
レッツ開発。

要件定義

まずは目的や必要な機能を明確化します。

  • とりあえず四則演算ができればよい
  • 使いたいときにすぐ使えるようにしたい
  • ある程度の見た目にする

機能は最小限に絞り、後で必要になってから付け足していこうと思いました。

外部設計

どういったプラットフォームで動かすのかを考えます。
web上で動かすため、HTMLとCSSでしょうか。(それくらいしかわからない)
また、縦持ちや横持ち、スマホでも使えるようにレスポンシブデザインを導入します。
幸い、簡単に使えるBootstrapというフレームワークがあるので、ありがたく頂戴します。

内部設計

どのようにプログラミングしていくかを決めていきます。
電卓の設計自体はプログラミング初心者に格好の教材となっており、ウェブ上に様々な例があるのでそれを拝借します。

開発・テスト

自分で開発し都度画面を確認、表記崩れが起きていないかなどチェックしていきます。

リリース

コーディングが終わったら、html、cssファイル等をgithubにアップロードしてweb上に公開。
サイトをホーム画面に追加することで、めでたくiPadでも1ポチで電卓が使えるようになりました。
下記URLから実際の電卓に飛べます。
https://platon-index.github.io/webcalc/

実際に作ってみて

非常に簡素なものとはいえ、自分で開発したプログラムが動くのを見るのはやはり楽しいですね。
画面サイズに合わせてボタンが横に広がるので、見た目もそれっぽく作れたかと思います。
参考にした記事のリンクを貼ろうと思いましたが、完成したら満足してすべてのページを閉じてしまいました🤪

ソースコード

本当はもっとシンプルに記述できると思うのですが、面倒で断念しました。
当初はボタンの大きさやフォントを一つ一つ指定していたので、少しは簡略化できたかなと思います。

「btn-lg」のところはCSSでひとまとめにできそうな気がします、が、調べてもわかりませんでした。Bootstrapでは記述方法が違うのでしょうか?
コードに色が付くとハッカーみたいでかっこいいですね(小学生並の感想)
※たぶんスマホで開くとめっちゃ崩れます。直し方はよくわかりません😃

<!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>Calculator</title>
    <!-- BootstrapのCSS読み込み -->
    <link href="bootstrap.min.css" rel="stylesheet">
    <!-- jQuery読み込み -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <!-- BootstrapのJS読み込み -->
    <script src="bootstrap.min.js"></script>
  </head>
  <style>
      button{
          width: 80px;
          height: 80px;
      }  
  </style>
  <body>
    <div class="container">
        <div class="table-responsive">
            <title>Calculator</title>
            <h2>Calculator</h2>
            <input style="font-size: 28px; text-align: right; width: 100%;"/><br />
            <script><!-- 実際の計算部分 -->
                function update( _v ){
                    document.querySelector( 'input' ).value = _v
                }
                function append( _v){
                    document.querySelector( 'input' ).value += _v
                }
                function calc(){
                    const v = document.querySelector( 'input' ).value
                    try {
                        const f = new Function( 'return ' + v )
                        update( f().toString() )
                    }catch(_error){
                        update(_error)
                    }
                }      
            </script>
            <div class="btn-group" role="group" aria-label="line1" style="width: 100%;">
                <button type="button" class="btn btn-light btn-lg" onclick= "update( '' )">C</button>
                <button type="button" class="btn btn-light btn-lg" onclick= "append( '**' )">^</button>
                <button type="button" class="btn btn-light btn-lg" onclick= "append( '**0.5' )"></button>
                <button type="button" class="btn btn-warning btn-lg" onclick= "append( '/' )">÷</button><br />
            </div>
            <div class="btn-group" role="group" aria-label="line2" style="width: 100%;">
                <button type="button" class="btn btn-outline-dark btn-lg" onclick= "append( '7' )">7</button>
                <button type="button" class="btn btn-outline-dark btn-lg" onclick= "append( '8' )">8</button>
                <button type="button" class="btn btn-outline-dark btn-lg" onclick= "append( '9' )">9</button>
                <button type="button" class="btn btn-warning btn-lg" onclick= "append( '*' )">×</button><br />
            </div>
            <div class="btn-group" role="group" aria-label="line3" style="width: 100%;"> 
                <button type="button" class="btn btn-outline-dark btn-lg" onclick= "append( '4' )">4</button>
                <button type="button" class="btn btn-outline-dark btn-lg" onclick= "append( '5' )">5</button>
                <button type="button" class="btn btn-outline-dark btn-lg" onclick= "append( '6' )">6</button>
                <button type="button" class="btn btn-warning btn-lg" onclick= "append( '-' )">-</button><br />
            </div>
            <div class="btn-group" role="group" aria-label="line4" style="width: 100%;">
                <button type="button" class="btn btn-outline-dark btn-lg" onclick= "append( '1' )">1</button>
                <button type="button" class="btn btn-outline-dark btn-lg" onclick= "append( '2' )">2</button>
                <button type="button" class="btn btn-outline-dark btn-lg" onclick= "append( '3' )">3</button>
                <button type="button" class="btn btn-warning btn-lg" onclick= "append( '+' )">+</button><br />
            </div>
            <div class="btn-group" role="group" aria-label="line5" style="width: 100%;">
                <button type="button" class="btn btn-outline-dark btn-lg" onclick= "append( '0' )">0</button>
                <button type="button" class="btn btn-outline-dark btn-lg" onclick= "append( '00' )">00</button>
                <button type="button" class="btn btn-outline-dark btn-lg" onclick= "append( '.' )">.</button>
                <button type="button" class="btn btn-warning btn-lg" onclick= "calc()">=</button>
            </div>
  </body>
</html>

雑な解説

1行目:HTMLっていう言語で書くよ
2行目:75行目とセットではさむよ。日本語で書くよ
3行目:14行目とセットではさむよ。何をはさめばいいかはよくわからないよ
4行目:UTF-8っていう文字コードで書くよ
5行目:インターネットエクスプローラーだとバグることがあるらしいから注意だよ
6行目:画面の幅にあわせて表示が変わるようにするよ。最初の大きさは1だよ
7行目:タイトルだよ。24行目との違いはわからないよ
9行目:BootstrapのCSS(着せ替え衣装)を読み込むよ
11行目:jQueryってやつを読み込むよ。何なのかはわからないよ
13行目:Bootstrapのjavascriptを読み込むよ。どんな動きをしてるのかはわからないよ
15行目:20行目とセットではさむよ。簡単な着せ替え衣装みたいなものだよ
16~19行目:ボタンの大きさを決めるよ。でも大きさを可変にしたから最低値保障みたい
21行目:74行目とセットではさむよ。ここがコンテンツになるよ
22行目:表示の大きさを可変にするらしいよ
23行目:これも表示の大きさを可変にするらしいよ。多分上と両方必要だよ
24行目:タイトルだよ。タブに表示されるよ
25行目:大きい文字で表示されるタイトルだよ
26行目:数字が入力されるフォームだよ。画面幅に合わせて長くして、文字の大きさと位置を決めるよ
27行目:43行目とセットではさむよ。実際に計算する部分だよ
28~30行目:「C」を押したときにフォームをクリアするよ
31~33行目:ボタンを押したらフォームに入力するよ
34~42行目:「=」を押したら計算するよ。エラーが出たら表示するよ。
44~73行目:ボタンだよ。1行ずつグループにして大きさを可変にしてるよ

結論:なんかよくわからないけど動いてるよ
f:id:Platon:20200924220518j:plain