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.
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
}
},
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)
}
}
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.
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">➕</p>
<p v-else class="info-letter"></p>
</div>
</template>
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: ""})
}
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)