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

Google Apps Scriptで競技かるたの読み札をWebアプリ化した

Last updated at Posted at 2024-02-07

作ったもの

https://script.google.com/macros/s/AKfycbwXI-uiPir7LjSJcGAE-58Zcry5MLHMvPYUmE45XvBoyiIRZ_msKi-hhh5D_u1TTeg/exec

機能

  • 競技かるたの読み札をランダムな順番で表示します
    • 読唱規定に則った読み方を表記しています
  • 混ぜ直したいときは上のシャッフルボタンを押します
  • どこまで読んだか確認できるように,読み札をタップで色をグレーに変えられます

作った経緯

趣味で競技かるたをしており、読み手をやることもあります。
読み札が手元にない場合もあるので,スマホで手軽に使えたら便利だと思い,作りました。

準備

サーバーを用意する必要がなく,ブラウザ上で簡単に作れそうなので,GoogleスプレッドシートとGoogle Apps Script(GAS)を組み合わせて作りました。

スプレッドシート

fuda_list シート

  • 百首の歌番号と和歌を入力するマスタシートです
  • 改行するための br タグ,色をつけるための font タグ,ふりがなを振るための ruby タグはセル内に入力してしまっています

image.png

yomi_list シート

  • 乱数から読み上げの順番を生成しています
  • 合わせて,ここでチェックボックスや,何枚目かの表記を各セルの1行目に入れています

image.png

input シート

  • シャッフルで乱数の再計算をさせたいときに,GASからこのシートに適当な値を入力するために用意しています

output シート

  • 1行目には,競技かるたで最初に読み上げる序歌を入れています
  • 2〜101行目に,読み札に含める内容を yomi_list シートから引っ張ってきています

image.png

GAS

GASは,スプレッドシートのコンテナバインドスクリプトとして作っています。
このように,GAS・HTML・CSS・JavaScriptでファイルを分けています。

image.png

GASのコード

コード.gs
const ss = SpreadsheetApp.getActiveSpreadsheet();

// index.htmlをテンプレートとしてHTMLを出力する関数。PWA化に必要なメタタグもここで入れます。
function doGet() {
  let output = HtmlService.createTemplateFromFile("index").evaluate();
  output.addMetaTag('viewport', 'width=device-width, initial-scale=1')
        .addMetaTag('apple-mobile-web-app-capable','yes')
        .addMetaTag('mobile-web-app-capable','yes')
        .setTitle("月読(読み札)")
        .setFaviconUrl('https://drive.google.com/uc?id={Googleドライブ内のファビコン画像のIDを入れます}&.png');
  return output;
}

// inputシートに「1」を入力することで再計算させ,読み札をシャッフルし直す関数
function reloadSheet() {
  ss.getSheetByName("input").getRange(1,1).setValue(1);
}

// outputシートから読み札の一覧を取得して返す関数
function generateYomiList() {
  return ss.getSheetByName("output").getRange(1,1,101).getValues();
}

// スクリプトのURLを取得する関数(リロードに使用)
function getScriptUrl() {
  let url = ScriptApp.getService().getUrl();
  return url;
}

HTML

<?!= HtmlService.createHtmlOutputFromFile("js").getContent(); ?>
<?!= HtmlService.createHtmlOutputFromFile('css').getContent(); ?>
上記はそれぞれjs.htmlcss.htmlの内容をこの位置に入れるための記述です。

index.html
<html>
    <?!= HtmlService.createHtmlOutputFromFile("js").getContent(); ?>
  <head>
    <?!= HtmlService.createHtmlOutputFromFile('css').getContent(); ?>
  </head>
  <body>
    <h1>読札アプリ <ruby><rb></rb><rp></rp><rt>つく</rt><rp></rp><rb></rb><rp></rp><rt>よみ</rt><rp></rp></ruby></h1>
    <p>
      <input type="button" onclick="reloadText()" value="  読み札をシャッフルする  ">
    </p>
    <div id='inserthyo'></div>
    <p>
      <a href="#"><input type="button" value="  ページの一番上に戻る  "></a>
    </p>
    <br><br>
    <h1>共有用QR・URL</h1>
    <p>
      <img src="{QRコードのURL}" width="250px" height="250px"/>
    </p>
    <p>
      <input type="button" onclick="copyUrl()" value="  URLをコピーする  ">
    </p>
  </body>
</html>

CSS

タップした札全体に色をつけるために,CSSを以下のようにしています

  • input[type=checkbox] に対して display:none; でチェックボックスを不可視にする
  • td要素に対して position:relative; を設定し,配下のlabel要素(札の文字全体)に対してdisplay:block;を設定することでtd要素内全部をチェックボックスのラベルにする
  • input:checked + label に対して背景色を設定する
css.html
<style type="text/css">
  body {
    background-color : #E1DAC3;
    font-size        : medium;
    font-family      : "Helvetica Neue", "Helvetica", "Hiragino Sans", "Hiragino Kaku Gothic ProN", "Arial", "Yu Gothic", "Meiryo", sans-serif;
  }
  h1 {
    color            : #333333;
    font-size        : xx-large;
  }
  table {
    border           : none;
    padding          : 0;
  }
  td {
    background-color : #FFFFFF;
    border-color     : #336633;
    border-width     : 0.3rem;
    border-style     : solid;
    border-radius    : 0.3rem;
    width            : auto;
    padding          : 0;
    line-height      : 2rem;
    position         : relative;
  }
  input[type=button] {
    color            : #FFFFFF;
    background-color : #336633;
    border           : none;
    border-radius    : 0.3rem;
    font-size        : medium;
    width            : auto;
    padding          : 0.5rem 1rem;
  }
  input[type=checkbox] {
    display          : none;
  }
  label {
    display          : block;
    padding          : 0.8rem 0.5rem 0.3rem 0.5rem;
  }
  input:checked + label {
    background-color : #CCCCCC;
  }
  iframe {
    border           : 0;
  }
  .num{
    font-size        : 0.8rem;
    position         : absolute;
    right            : 0.5rem;
    bottom           : 0.1rem;
  }
</style>

JavaScript

  • 最初にスプシから取ってきたデータをもとに読み札のテーブルを作る関数や,ボタンを押したときの挙動についてここで設定しています
js.html
<script type="text/javascript">
  // スプシから読み札の一覧を読み込む
  function loadsheet(){
    google.script.run.withSuccessHandler(outSpreadsheet).generateYomiList();
  }
  window.addEventListener('load', loadsheet);

  // 読み札テーブルの作成
  function outSpreadsheet(spreadsheet_data){
    var htmlTable = '<table id="tableData" border=1>';
    for(var row = 0; row < spreadsheet_data.length; row++){
      htmlTable += '<tr>';
        htmlTable += '<td>' + spreadsheet_data[row][0] + '</td>';
      htmlTable += '</tr>';
    }
    htmlTable += '</table>';
    document.getElementById("inserthyo").innerHTML = htmlTable;
  }

  // 読み札のシャッフル
  function reloadText(){
    let flag = window.confirm("読み札をシャッフルしますが,いいですか?");
    if(flag) {
      google.script.run.reloadSheet();
      update();
    }
  }

  // ページの再読み込み
  function update() {
    google.script.run
      .withSuccessHandler(result).getScriptUrl();
      function result(url){
        window.open(url, '_top');
      }
  }
</script>

アプリを公開する

  • GASが完成したら,GASの画面の右上にあるデプロイ→新しいデプロイからデプロイします
    • 種類を「ウェブアプリ」に,アクセスできるユーザーを「全員」に設定してから「デプロイ」します
    • 初回のみ,権限を許可するためのポップアップが出ます

image.png

  • デプロイ後,「ウェブアプリ」の下に書かれているURLが公開されたWebアプリのURLです
  • 2回目以降のデプロイでは「新しいデプロイ」から行うとURLが変わります
    • URLを変えたくない場合は「デプロイを管理」から編集をクリックし,バージョンを新バージョンとしてデプロイします

image.png

今後やりたいことなど

競技かるたでは百人一首の100枚のうち,ランダムな50枚を使います。使わないほうの50枚は読み上げるけれど場にない「空札」と呼ばれます。
練習時間が短い場合,全試合で使う札を揃えた上で,空札を何枚か抜いて試合することがあります。どの札を抜くのが良いかいい感じに決めてくれるような機能も実装してみたいと考えています。

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