16
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

PWAAdvent Calendar 2019

Day 18

Vue.js / Web Speech API で作る、 PWA対応 英単語学習ソフト

Last updated at Posted at 2019-12-17

この記事は「PWA Advent Calendar 2019」の18日目の記事です。

今年の春、Progressive Web Apps や Firebase の練習がてら、英単語学習ソフトを開発しました。
(が、そのまま放置していた)

作りっぱなしももったいないので、アドベントカレンダーに乗じてご紹介します。

以下のような特徴があります。

  • Vue.js を利用したMPA(Multi-page Application)
  • Progressive Web Apps 対応。Windows10/スマホにインストールして、オフラインで動作。
  • 英単語の発音をクリックして確認できる (Web Speech API 利用)
  • Firebase のHosting機能を利用して公開
  • 選択肢と回答をランダムに生成。英単語アプリにありがちな「同じ選択肢と回答が繰り返され、出題パターンを覚えてしまう」ことがないようにした。(800の4乗x10問で、組み合わせは4兆通りぐらい?)

be800_1.png

be800_2.png

開発中のメモをもとに、いくつか備忘録を記述します。

Web Speech API による英語音声の確認

アプリを起動すると、英単語と4つの選択肢が表示されます。英単語をクリック・タップすると、英語の発音を確認できます。
Speech Synthesis API という、Web Speech APIの音声合成機能を利用しました。

          pronounce: function () {

            // confirm English word's pronounciation

            let u = new SpeechSynthesisUtterance();
            u.lang = 'en-US';
            u.text = document.getElementById('englishWord').innerHTML;
            u.volume = "1";
            speechSynthesis.speak(u);

          }

※Speech Synthesis API の使い方については拙稿「Web Speech API を 利用して 英単語の音声確認をするアプリを作る」にまとめました。

Service Worker によるデータキャッシュ

html・CSS・効果音などのアセットファイル類を、Service Worker でまとめてキャッシュしています。

バージョンをキャッシュのキーとして登録。バージョン情報に更新があった場合、キャッシュパージ後、ファイルをキャッシュしなおすようにしました。

const CACHE_NAME = `BasicEnglish800-${version}`;

---- 中略 ----

// Service Worker へファイルをインストール

self.addEventListener('install', function (event) {
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(function (cache) {
        console.log('Opened cache');
        return cache.addAll(urlsToCache);
      })
  );
});

// リクエストされたファイルが Service Worker にキャッシュされている場合
// キャッシュからレスポンスを返す

self.addEventListener('fetch', function (event) {
  if (event.request.cache === 'only-if-cached' && event.request.mode !== 'same-origin')
    return;
  event.respondWith(
    caches.match(event.request)
      .then(function (response) {
        if (response) {
          return response;
        }
        return fetch(event.request);
      }
      )
  );
});

// Cache Storage にキャッシュされているサービスワーカーのkeyに変更があった場合
// 新バージョンをインストール後、旧バージョンのキャッシュを削除する
// (このファイルでは CACHE_NAME をkeyの値とみなし、変更を検知している)

self.addEventListener('activate', event => {
  event.waitUntil(
    caches.keys().then(keys => Promise.all(
      keys.map(key => {
        if (!CACHE_NAME.includes(key)) {
          return caches.delete(key);
        }
      })
    )).then(() => {
      console.log(CACHE_NAME + "activated");
    })
  );
});

※Service Workerの使い方や詳細については拙稿「Progressive Web Apps (PWA) 学習者のメモ その1  (Service Worker)」にまとめました。

Vue.js で問題を生成、回答記録を追跡

Vue.js を利用して、回答数を記録。
最初に10問分の英単語・選択肢・回答を、ランダムに生成。
配列に単語・回答・選択肢のデータを格納。
問題を解いて「次へ」をクリック・タップすることで、配列を切り替え、次の問題を表示。
1問解くたびに、次の問題へ切り替え。

10問終了後に正誤のデータを確認し、回答を記録するようにしました。


      const vm = new Vue({
        el: '#el',
        data() {
          return {
            arr: answerList,
            count: 0,
            choice: quizList,
            result: [],
          }
        },
        methods: {
          check: function (event) {

            // check user's answer each by each

            let target = document.getElementById("answerOptions");

            target.setAttribute('style', 'pointer-events: none;');
            let rightAnswer = this.arr[this.count].Japanese;
            let chosenAnswer = event.target.innerHTML;

            if (rightAnswer === chosenAnswer) {

              correctSound.play();
              message.innerHTML = "正解!";
              addAnswer("");

            } else {

              wrongSound.play();
              message.innerHTML = "残念!";
              addAnswer("×");

            }

            this.count === 9 ? complete() : unComplete();
          },

※Vue.js を利用した回答の切り替え(=配列の切り替え)については、拙稿「Vue.js で 配列とJSONの切り替え表示を行う」にまとめました。

振り返り

一つ一つは単純なコードですが、組み合わせることで、それなりにアプリとして形になった気がしました。

できれば

  • Firebase のユーザー認証を利用して、リアルタイムDBに回答記録を保存
  • 全アプリユーザーの間で、どの単語の誤答率が高いか、統計を取る

までやってみたかったのですが、時間切れで実装できず。
Firebaseの利用はHostingのみとなりました。

そのうち時間を作ってチャレンジしてみたいと思います。

備考

以下のサイトのデータ・情報を元に開発しました。

16
15
1

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
16
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?