活字読めない人間なので読み上げアプリに助けてもらう

## 活字が苦手です・・・
**私は活字を読むことが苦手です・・・** ので昔から本が読めません・・・
それにより現在ひとつの問題を抱えております。
それは **大好きなラグビーのルールが覚えられない！！** という事です。

のっとりりーすざぼーる？のっとろーるあうぇい？？のっとすとれーと？？？
似てる名前のルールが多いし、文章で読んでもよくわからん！となっております。

という事でそんな自分を助ける為に、**JavaScriptとWeb Speech APIを使って、ラグビーのルールを読みあげてくれるアプリを作ってみました！**

## ゴールの設定
今回作成するアプリでは以下の点をゴールに設定して実装していきます！
言語切り替え機能は、**審判が英語で話す事への対策としておまけで実装します！**

:::note info
**・ ルール名のボタンを押すと説明を読みあげてくれるアプリを作る
・ 日本語と英語の切り替え機能を付ける**
:::

## 完成品はコチラ！
作成したアプリはこちら！紹介動画と共にご覧ください！
**※音がでるので注意してください※**
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">リーグワン開幕まであと2週間ちょい🏉<br>せっかくなのでラグビーのルールを読みあげてくれるアプリを作成しました！<br>日本語・英語の切り替え機能のおまけ付き！<a href="https://twitter.com/hashtag/protoout?src=hash&amp;ref_src=twsrc%5Etfw">#protoout</a> <a href="https://twitter.com/hashtag/javascript?src=hash&amp;ref_src=twsrc%5Etfw">#javascript</a> <a href="https://twitter.com/hashtag/HTML?src=hash&amp;ref_src=twsrc%5Etfw">#HTML</a> <a href="https://twitter.com/hashtag/CSS?src=hash&amp;ref_src=twsrc%5Etfw">#CSS</a> <a href="https://twitter.com/hashtag/%E3%83%A9%E3%82%B0%E3%83%93%E3%83%BC?src=hash&amp;ref_src=twsrc%5Etfw">#ラグビー</a> <a href="https://twitter.com/hashtag/%E3%83%A9%E3%82%B0%E3%83%93%E3%83%BC%E5%A5%BD%E3%81%8D%E3%81%A8%E7%B9%8B%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#ラグビー好きと繋がりたい</a> <a href="https://twitter.com/hashtag/Rugby?src=hash&amp;ref_src=twsrc%5Etfw">#Rugby</a> <a href="https://twitter.com/hashtag/%E3%83%AA%E3%83%BC%E3%82%B0%E3%83%AF%E3%83%B3?src=hash&amp;ref_src=twsrc%5Etfw">#リーグワン</a> <a href="https://t.co/cG8re688vH">pic.twitter.com/cG8re688vH</a></p>&mdash; oooookawa (@ooooooooookawa) <a href="https://twitter.com/ooooooooookawa/status/1726744885892698304?ref_src=twsrc%5Etfw">November 20, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

### ■Netlifyページ
https://655b01defb2a474a59ae44cd--fluffy-zuccutto-07d054.netlify.app/

### ■Codepen
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="YzBeVKv" data-user="oooookawa" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/oooookawa/pen/YzBeVKv">
  ラグビールールブック</a> by oooookawa (<a href="https://codepen.io/oooookawa">@oooookawa</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

### ■QRコード
QRコードを読み取ればスマートフォンからもお試しできます！
![QR.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3567275/aa9a245d-c25e-e384-15ac-7c745e5f1ea0.png)


## 環境準備
今回使用した環境は以下の通りです。
・CodePen
・HTML
・CSS
・JavaScript
・Web Speech API

## 実装ポイント

### ①必要情報を配列で定義

後述するメイン画面と読み上げ処理で使用する為の情報を定義し、配列で格納します。
カンマ区切りで、**画像,日本語ルール名,英語ルール名**を定義しております。

```javascript
const data = [
  ["https://i.gyazo.com/33d60b1e06928f907ba59471a45a62d2.png", "ノックオン", "Knock on"], 
  ["https://i.gyazo.com/6f72346514acc6808e511d913ff8c4bb.png","スローフォワード", "Throw forward"],
  ["https://i.gyazo.com/d9becac679efd7eeaa759635809eb77a.png", "ノットリリースザボール", "not-release-the-ball"],
  ["https://i.gyazo.com/e6e6fe788b300ca9979c4b0ab592f8e6.jpg", "ノットロールアウェイ", "not-roll-away"],
  ["https://i.gyazo.com/51f739eef1e4c25ac6f20cc29f105909.png","コラプシング", "Collapsing"],
  ["https://i.gyazo.com/dcd47355dbca76c8eea3b77a2f813c8d.jpg", "50-22", "fifty-twenty two"],
  ["https://i.gyazo.com/1d81f79f12ad8535e1cfa47ec380f01b.png", "オブストラクション", "Obstruction"],
  ["https://i.gyazo.com/111a5473c21e6a4bc4b25711c12625da.jpg", "ノットストレート", "not-straight"]
];
```

### ②メイン画面の生成
①の配列で定義した情報を使用して、メイン画面のカード部分を作成します。
配列から画像URLと日本語ルール名を取得し、[カード内容の表示]箇所で画面を生成しております。

```javascript
/* メイン画面のカードを8個作成 */
window.onload = function () {
  for (let i = 0; i < 8; i++) {
    create(i);
  }
}
 
/* メインカードの作成 */
function create(i) {

  /* メインカードの成形 */
  let main = document.createElement("div")
  main.className = "main";
  main.onclick = function () {
    
    //事前に作成したデータを使用して選択
    speak(data[i][select.selectedIndex + 1], select.value);    
  }

  let image = new Image();
 
  //data内の画像を表示
  image.src = data[i][0];         

  //配列内の日本語文字列を表示
  let comment = document.createElement("p");
  comment.className = "comment";
  comment.append(data[i][1]);

  //カードの表示
  main.appendChild(image);
  main.appendChild(comment);

  document.getElementById("container").appendChild(main);
}  
```

### ③読み上げ処理
HTMLで選択した[日本語・英語]の言語情報から元に配列から取得した文字列によって、説明文をテキストに格納して読み上げを行っております。

```javascript
/* 音出力 */
function speak(text, language) {
  window.speechSynthesis.cancel(); // 初期化

  /* 選択内容の説明文をテキストに変換 */
  if(text == "ノックオン"){
    text = "ノックオン。ボールを前に落とす反則のこと。相手ボールのスクラムから試合が再開される。";   
  }else if(text == "Knock on"){
    text = "Knock on. One of the most common fouls in rugby, dropping the ball forward. The match restarts with a scrum of the opponent's ball.";
　～省略～
  
  const speechMsg = new SpeechSynthesisUtterance();
  speechMsg.lang = language;      //言語設定
  speechMsg.text = text;          //投稿設定

  window.speechSynthesis.speak(speechMsg);   //音出力
}
```

## あとがき

本当は今回の内容にプラスαで以下の内容を実装したかったのですが、時間が足りずにギブアップしてしまいました・・・・・この点は今後の課題という事で実装したいと思います。

:::note warn
**・ 言語の切り替えでメイン画面のルール名も英語に変更したかった
・ メイン画面にルール解説の動画リンクを付けたかった**
:::

また、前回作成したラグビーメンバー紹介アルバムと合体させて、それっぽいラグビー専門サイトを作ってみるのも面白そうだなと思ってます！これも今後やってみようと思います！

https://genuine-monstera-369513.netlify.app/


最後までご覧頂きありがとうございました！