【Vue3でwebアプリをつくろう4】英文読み上げ機能を追加する

記事の一覧はこちらから。

この連載ではVue3を使って英文法の学習を行うwebアプリをつくっていきます。今回は,英文を音声で読み上げる機能を追加し,全体の構成をもう少し見直していきます。

読み上げ機能の準備

英文をクリックすると英文が一瞬光り(ハイライト),音声で読み上げる機能を追加します。

const RootComponent = {  
  created() { //捨てgetVoicesの実行
    const uttr = new SpeechSynthesisUtterance();
    const voices = window.speechSynthesis.getVoices();
  }
}

Chrome(またはEdge)にはもともとブラウザの機能として,テキストから音声を再生させるspeechSynthesisというものがあり,これを使っていきます。

まず,前準備としてVueのルートコンポーネントの中にcreated()を作ります。これはコンポーネントが作られたときに実行される部分です。

ここでいったんspeechSynthesisのインスタンスとgetVoices()を実行します。getVoices()はブラウザが再生できる音声の種類などの情報を返すメソッドですが,なぜが1回目は空の情報を返すというバグがあるため,最初に一度,不要なgetVoices()を実行しておきます。

template: `
  ・・・・・・
  <p class="en-st" v-html="enSentence()" @click="execSpeech()"></p>

テンプレートの英文を表示する部分に@click="execSpeech()"を書いておきます。英文をクリックすると,メソッドexecSpeech()を呼び出します。

methods:
    execSpeech() {
      highlightEnSentence();    //英文をハイライトする
      speechEnSentence(this.texts[this.index].en); //英文の読み上げ
    }

メソッドから,英文をハイライト表示する関数highlightEnSentence()と,音声を読み上げる関数speechEnSentence()を呼び出します。また,読み上げる英文の文字列を引数として渡します。

ハイライトエフェクトを行う

//英文をハイライトする
export function highlightEnSentence() {
	let elem = document.querySelector('.en-st');
	elem.classList.add('highlight-en-sentence');
	elem.addEventListener('animationend', () => {
		elem.classList.remove('highlight-en-sentence');
	}, false);
}
.highlight-en-sentence {
  animation: highlight-animation 1s ease-out;
}
@keyframes highlight-animation {
  0% {
    background-color: #fff;
  }
  10% {
    background-color: #51ab9f;
  }
  100% {
    background-color: #fff;
  }
}

英文をハイライト表示する関数とスタイルシートの設定です。

英文をクリックすると英文全体がピカっと光ったあと,しばらくして消えます。これはVueの機能で作れるわけではないので,直接DOM操作を行って実現します。

まず,querySelector()で英文が表示されている部分のDOM要素を取得します。

classList.add()はスタイルを追加します。ここではアニメーションを行うcssを追加することで,アニメーションを開始させます。

次にイベントリスナーでanimationendを設置します。

イベントリスナーとは,「マウスがクリックされた」など特定のイベントが発生したときに,そこに書かれた処理を行うものです。

イベントリスナーの animationend はcssのアニメーションが終了したときに発火します。ここでは,remove()でスタイルを削除してもとに戻しています。

css側の詳しい説明は省きますが,animation @keyframes という機能を使って,背景の色が緑から白に徐々に変化していくアニメーションを実行しています。

読み上げ機能

export function speechEnSentence(elem) {
  speechSynthesis.cancel();     //再生中の音声があればキャンセル
  let uttr = new SpeechSynthesisUtterance();  //インスタンス
  const voices = speechSynthesis.getVoices(); //音声リストの取得
  uttr.voice  = voices[5];      //女性の声
  uttr.volume = 1.0;            //音量
  uttr.rate   = 0.8;            //読み上げ速度
  uttr.pitch  = 1.05;           //音程
  uttr.lang   = 'en-US';        //言語
  uttr.text   = elem;           //読み上げテキスト
  speechSynthesis.speak(uttr);  //再生
}

読み上げ機能です。ここで,再びspeechSymthesisをインスタンスし直してgetVoices()を実行します。

そしてインスタンスで生成したオブジェクトuttrに声の種類や音量などの設定を送り込みます。この関数は読み上げる英文を引数elemで受け取るので,uttr.text=elemとして読み上げるテキストのデータを送ります。

最後にspeak(uttr)で読み上げが開始されます。

voicesにはブラウザで再生できる音声のリストが格納されています。今回はアメリカ人女性の声を使いますが,お使いのブラウザによって異なる可能性があります。その場合には,voices[5]の数値を変更してみてください(数値で直接指定する方法は本来望ましくありませんが,ここでは手を抜きます)。