DEV Community

Cover image for Abecedario Espanol
subliminal_大衛
subliminal_大衛

Posted on

Abecedario Espanol

My girlfriend is from Sevilla (Spain) and is currently looking for a job as language or history teacher in Berlin. I wanted to help her a bit by creating a website for her. While the website is far from being ready, we decided to begin with a teeny-tiny app that teaches you to pronounce the spanish alphabet, which has quite a few pecularities. The alphabet is represented by little black boxes with clickable letters. Special character are being identified by a small black cross that reveals more info when clicked.

The prototype is currently deployed on Netlify: teresais-alfabeto. The source code is on Gitlab.

Screenshot of the site

How does the Browser speak spanish?

What may appear complicated is in fact really easy. I learned the basics in Wes Bos’s wonderful Vanilla JS course JavaScript30. With only a few lines of code you can use the SpeechSynthesis Constructor by MDN Web Docs. So all i really had to do was to define a new object instance in the data section of my App.vue.

Ups! Did I mention that I used Vue for the site? If you don’t know what Vue is you’ll find a free tutorial on the Scrimba site. It is really basic but should suffice to understand my code.

Anyway I defined some variables in the data section, namely synth and pronounciation:

data () {
    return {
      data: this.$store.state.alphabet,
      synth: window.speechSynthesis,
      voiceSpanish: [],
      pronounciation: new window.SpeechSynthesisUtterance
    }
  },
Enter fullscreen mode Exit fullscreen mode

In the method section I started with the method speakLetter()

methods: {
    speakLetter({msg}) {
      var voiceList = this.synth.getVoices()
      this.voiceSpanish = voiceList.filter(item => item.name === "Jorge")
      this.pronounciation.text = msg.toLowerCase()
      this.pronounciation.voice = this.voiceSpanish[0]
      this.synth.speak(this.pronounciation)
    }
}
Enter fullscreen mode Exit fullscreen mode

First I call the list of available voices with the .getVoices()-method using the synth-variable we declared above and filter through it looking for the “Jorge”-voice. (My daughter seems to like this particular voice ;-)) Then we’ll set the text-attribute of the SpeechSynthesisUtterance instance to the text submitted in the function parameter and the voice-attribute to the voice of “Jorge”. Finally the speak()-method does the job of firing the voice.

The LetterShow-Component

The LetterShow-component is being called by App.vue to show the responding letters. For this purpose I have prepared a data.json-file that i’ve loaded into the Vuex-store.

Foto of a code partition

It is really just an object that contains the letters and indicates if they have some special features or not. If so, those are being specified in the infotextRojo and infotextVerde-keys (Indicating strong and weak consonants in the spanish language).

I’m looping through this object with a v-for-directive and showing every letter with the LetterShow-component. Here is the HTML-part of it:

<template>
  <div class="letter-box">
      <h1 class="main-letter" @click="speak">{{ msg }}</h1>
      <p v-if="special" class="info-letter" @click="showModal">&#x2795;</p>
      <p v-else class="info-letter"></p>
  </div>
</template>

Enter fullscreen mode Exit fullscreen mode

If the letter is special we’ll show a cross that activates the Modal-component to show the special cases. Both, the LetterShow and the Modal-component, fire Custom Events to trigger the speakLetter-method. That’s about it.

Misc

I guess my explication is somewhat abstract, so I’m inviting you to clone the repository and play around with it on your machine.

Currently it is not running on the mobile browsers I tried and I’m guessing it has to do with the experimental nature of the SpeechSynthesis Constructor.
Also, to make sure that I’m really getting the “Jorge”-voice I had to fire the speakLetter-method once on page mount, because the SpeechSynthesis starts with the voice of an american woman by default.

mounted() {
    this.speakLetter({msg: ""})
  }
Enter fullscreen mode Exit fullscreen mode

As you can see, i’m just calling the speakLetter*-method with an empty message, so that it is forced to load “Jorge” afterwards.

Have fun playing around!

Top comments (0)