【マジ卍】ギャルのお悩み相談アプリ　#Bootstrap #ズッ友 

# 大丈夫そ？
私はギャルが好きだ。
語弊があるので言い換えると、ギャルの「ハッピーに生きよ♥」というマインドが好きだ。
ギャルと話をして「超ウケるー！」と言ってもらえるとなんか元気になれる。
しかし私には、**ギャルの友達はいない。**よし、作ろう。

# マジ卍 :fire: :boom: :fire: :boom:

https://pensive-kowalevski-385c77.netlify.app/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2122226/c5ccbdf5-7210-9e56-156d-ae4c2a2dc31b.png)

**＜使い方＞**
1.　「ギャルピに話しかける」ボタンを押す。
2.　　話しかける。　<font color="blue">※マイク使用確認のメッセージが表示されたらOKにする。</font>
3.　　相談話の場合は「ギャルピの返事を聞く」を押す。
4.　　笑い飛ばして欲しい場合は「ギャルピに笑い飛ばしてもらう」ボタンを押す。

※ 3、4ボタンはどのタイミングで押しても、同じ内容の返事。


# 使った感想「ギャルピ、いい子」
使った感想。**「話しかける」ボタンいるか・・・？**
本当はこちらの話しかけの内容によって、ギャルピの返事を自動で判断させたかった。
けれど今回の場合はギャルピ返事を人間側でチョイスするので「話しかける」機能が浮いてしまっている。

ただ、**悩みが文字に起こされるとちょっと気持ち的に落ち着く**のと、上手く音声が認識されなくて**なんでその言葉になったの～！ガハハ！**的な楽しみ方ができたのでこれはこれで良い気がする。
何を言っても「超ウケるー（棒読み）」と言ってくれるギャルピ、これからもズッ友だょ・・・！

# ソースコード
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="bGrMXBv" data-user="morishitanana" 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/morishitanana/pen/bGrMXBv">
  ギャルピお悩み相談ver.もしもし</a> by mshita (<a href="https://codepen.io/morishitanana">@morishitanana</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>


## 絵文字 :sparkling_heart: :sparkling_heart: :sparkling_heart: :sparkling_heart:

```html:HTML
<b>&#x1f496;&#128140; ギャルピへのお悩み相談 &#128140;&#x1f496;</b>
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2122226/c506de2a-c2dd-24d7-ec80-af51d5be88af.png)
ギャルがテーマなので、**絵文字が必須！**
「HTML　絵文字」で検索すると、HTML上で使える絵文字が沢山出てくるので、そちらを参考にとにかく張り付ける。
（参考）[Let’s EMOJI](https://lets-emoji.com/emojilist/emojilist-1/)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2122226/ecfcb854-7bbb-b1fd-4583-010472d7102c.png)
ボタンの中に設定することも可能。

## Bootstrap
レイアウト設定は、Bootstrap[（公式）](https://getbootstrap.jp/docs/4.3/getting-started/introduction/)を使用。スタイリッシュすぎて逆に苦戦。
基本的には公式で公開している機能を使用。

codepen上でBootstrapを使うときの手順については、忘れそうだったので別記事でまとめた。
・[HTMLスーパー初心者、CodepenでBootstrapを使う](https://qiita.com/mnana/items/79ff8f4bc5b3cc42dbd0)

### 淡い色設定
```html:HTNL
<div class="container text-center alert alert-danger" id="app">
```
Bootstrapで使用できる色は限られている。
どうしても背景を淡い色にしたかったので、`alert alert-danger`を1行目に設定。
danger（赤）からいい感じのピンク色に。
ただし、**この使い方が合っているのかは分からない。**


## Web Speech API
### 音声認識した内容を、文字起こしする
```html:HTML
<p>
  <b>ギャルピ、ちょっと聞いてよ～！！</b>&#x1f622;&#x1f622;<br>
    <button @click="listen" class="btn btn-danger btn-lg">{{ recogButton }}</button>
<br><br>
  <b>&#x1f496;&#128140;ギャルピへのお悩み相談&#128140;&#x1f496;</b><br>
  {{ result }} <br>
</p>
```
```js:JS
const app = new Vue({
  el: '#app',
  
  data: {
    recogButton: 'ギャルピに話しかける',
    recog: null,
    result: '',
    speech: null,
    message: '',
  },
  
  mounted() {
    // 音声認識の準備
    const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition || window.mozSpeechRecognition || window.msSpeechRecognition || null;
    this.recog = new SpeechRecognition();
    this.recog.lang = 'ja-JP';
    this.recog.interimResults = false;
    this.recog.continuous = false;
    
    // 音声認識が開始されたら
    this.recog.onstart = () => {
      this.result = '';
      this.recogButton = 'ちゃんと聞いてるし！';
    };
    
    // 音声を認識できたら
    this.recog.onresult = (event) => {
      // 認識されしだい、this.resultにその文字をいれる
      // Vueなので、文字をいれただけで画面表示も更新される
      this.result = event.results[0][0].transcript;
    };
    
    // 音声認識が終了したら
    this.recog.onspeechend = () => {
      this.recog.stop();
      this.recogButton = 'まだ話足りない？';
    };
    
    // 認識できなかったら
    this.recog.onerror = () => {
      this.result = '（何言ってるか分かんなかったな…）';
      this.recog.stop();
      this.recogButton = 'まだ話足りない？';
    };
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2122226/687a5518-a861-87f6-f356-02a6460688b5.png)
音声認識した内容を、文字で表示させる。

### ボタンを押したら発話させる（文言指定）
```html:HTML
<div class="row my-5">  
  <div class="col-sm-6 mx-auto">
    <button @click="say" class="btn btn-danger btn-lg">  ギャルピの返事を聞く  &#128536;&#x1f91e;&#x1f4ac;&#x1f495;　	
    </button>
  </div>
</div>
```

```js:JS
// 発話の準備
this.speech = new window.SpeechSynthesisUtterance();
this.speech.lang = 'ja-JP';
// または、ブラウザが対応している言語のうちja-JPな最初のボイスを使う
window.speechSynthesis.onvoiceschanged = () => {
const voices = window.speechSynthesis.getVoices();
    this.speech.voice = voices.find(voice => voice.lang == 'ja-JP');
    console.log(this.speech.voice);
   };
},
  
methods: {   
  // 認識（聞き取り）
  listen() {
    this.recog.start(); 
  },
    
// ギャルピ返事
async say() {
  return new Promise((res) => { 
    this.speech.text = 'よく分かんないけど、頑張っててえらすぎじゃね？';
    this.speech.onend = () => res();
    speechSynthesis.speak(this.speech);
  });
},

},
});
```
「ギャルピの返事を聞く」ボタンを押すと、「&#x1f50a;**よく分かんないけど、頑張っててえらすぎじゃね？**」と言ってくれる。
よく分かんないながらも褒めてくれるギャルピは最高のマブダチ:sparkles::star::sparkles::star::sparkles::star:


# 改善の余地あり
音声認識した内容の活用方法について、改善の余地あり。
会話っぽいものが自動でできると理想的なので、引き続きギャルピとの仲を深めるために精進したい。