Skip to content

Commit 9ba62de

Browse files
committed
made speech synthesis project
1 parent 2baf1df commit 9ba62de

File tree

6 files changed

+198
-2
lines changed

6 files changed

+198
-2
lines changed

23-Speech-Synthesis/README.md

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# 23 - Speech Synthesis
2+
3+
## About the Project
4+
This project uses *Web Speech API* in which it converts text to speech. There are various things you can control like voice, rate, pitch & text. Then it converts text into speech format.
5+
6+
## Things I learned
7+
- Learned about **Web Speech API** where there are two things `SpeechRecognition` & `SpeechSynthesis`. One recognise the speech of & other read text & tell it to speech.
8+
- `SpeechSynthesisUtterance` Web API. Learned a lot about it. Its various functions that can be used like `text`, `rate`, `pitch`, `voice` & various other useful things.
9+
- `window.speechSynthesis` this has many functions like `speak`, `pause`, `resume`, `cancel` & this is where we put our speechSynthesisUtterance object into.
10+
- Learned more about the input fields & how to access them & modify them in JavaScript.
11+
- About various voices availale in our browser & how to them.
12+
- If anyone want to understand about then I would suggest [this](https://www.smashingmagazine.com/2017/02/experimenting-with-speechsynthesis/) article. I read it & got the basic understanding of how to use it.
13+
14+
## Some important things
15+
- Made responsive website & make it look aesthically pleasing.
16+
- In `speechSynthesis` it has event called `voicechanged` event that we used to detect that all things loaded.

23-Speech-Synthesis/favicon.png

469 Bytes
Loading

23-Speech-Synthesis/index.html

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
4+
<head>
5+
<meta charset="UTF-8">
6+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
7+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
8+
<title>Speech Synthesis</title>
9+
<link rel="stylesheet" href="style.css">
10+
<link rel="shortcut icon" href="favicon.png" type="image/x-icon">
11+
<script src="main.js" defer></script>
12+
</head>
13+
14+
<body>
15+
<div class="voiceinator">
16+
<h1>The Voiceinator 5000</h1>
17+
18+
<select name="voice" id="voices">
19+
<option value="">Select A Voice</option>
20+
</select>
21+
22+
<label for="rate">Rate</label>
23+
<input type="range" name="rate" id="rate" min="0" max="3" value="1" step="0.1">
24+
25+
<label for="pitch">Pitch</label>
26+
<input type="range" name="pitch" id="pitch" min="0" max="2" step="0.1">
27+
28+
<textarea name="text" id="text">Hello! I love JavaScript ❤️</textarea>
29+
30+
<button id="stop">Stop!</button>
31+
<button id="speak">Speak</button>
32+
</div>
33+
</body>
34+
35+
</html>

23-Speech-Synthesis/main.js

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Creating speechSynthesisUtterance object
2+
const msg = new SpeechSynthesisUtterance;
3+
4+
let voices = [];
5+
const voicesDropdown = document.querySelector('[name="voice"]');
6+
const options = document.querySelectorAll('[type="range"], [name="text"]');
7+
const stopButton = document.querySelector('#stop');
8+
const speakButton = document.querySelector('#speak');
9+
10+
msg.text = document.querySelector('[name="text"]').value;
11+
12+
function populateVoices() {
13+
voices = this.getVoices();
14+
// console.log(voices);
15+
16+
const voiceOptions = voices
17+
// .filter(voice => voice.lang.includes('en'))
18+
.map(voice => `<option value="${voice.name}">${voice.name} (${voice.lang})</option>`)
19+
.join('');
20+
voicesDropdown.innerHTML = voiceOptions;
21+
}
22+
23+
function setVoice() {
24+
// console.log(`changing to ${this.value}`);
25+
msg.voice = voices.find(voice => voice.name === this.value);
26+
toggle();
27+
}
28+
29+
// this function logic is very cool
30+
function toggle(startOver = true) {
31+
speechSynthesis.cancel();
32+
if(startOver) {
33+
speechSynthesis.speak(msg);
34+
}
35+
}
36+
37+
function setOption() {
38+
// console.log(this.name, this.value);
39+
msg[this.name] = this.value;
40+
toggle();
41+
}
42+
43+
window.speechSynthesis.addEventListener('voiceschanged', populateVoices);
44+
voicesDropdown.addEventListener('change', setVoice);
45+
46+
options.forEach(option => option.addEventListener('change', setOption));
47+
48+
speakButton.addEventListener('click', toggle);
49+
stopButton.addEventListener('click', () => toggle(false));

23-Speech-Synthesis/style.css

+95
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
@import url('https://fonts.googleapis.com/css2?family=Pacifico&display=swap');
2+
3+
html {
4+
box-sizing: border-box;
5+
font-size: 10px;
6+
}
7+
8+
*,*:before,*:after {
9+
box-sizing: inherit;
10+
}
11+
12+
body {
13+
margin: 0;
14+
padding: 0;
15+
font-family: sans-serif;
16+
background-color: #FF715B;
17+
background-color: #ff715b;
18+
background-image: url("data:image/svg+xml,%3Csvg width='180' height='180' viewBox='0 0 180 180' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M81.28 88H68.413l19.298 19.298L81.28 88zm2.107 0h13.226L90 107.838 83.387 88zm15.334 0h12.866l-19.298 19.298L98.72 88zm-32.927-2.207L73.586 78h32.827l.5.5 7.294 7.293L115.414 87l-24.707 24.707-.707.707L64.586 87l1.207-1.207zm2.62.207L74 80.414 79.586 86H68.414zm16 0L90 80.414 95.586 86H84.414zm16 0L106 80.414 111.586 86h-11.172zm-8-6h11.173L98 85.586 92.414 80zM82 85.586L87.586 80H76.414L82 85.586zM17.414 0L.707 16.707 0 17.414V0h17.414zM4.28 0L0 12.838V0h4.28zm10.306 0L2.288 12.298 6.388 0h8.198zM180 17.414L162.586 0H180v17.414zM165.414 0l12.298 12.298L173.612 0h-8.198zM180 12.838L175.72 0H180v12.838zM0 163h16.413l.5.5 7.294 7.293L25.414 172l-8 8H0v-17zm0 10h6.613l-2.334 7H0v-7zm14.586 7l7-7H8.72l-2.333 7h8.2zM0 165.414L5.586 171H0v-5.586zM10.414 171L16 165.414 21.586 171H10.414zm-8-6h11.172L8 170.586 2.414 165zM180 163h-16.413l-7.794 7.793-1.207 1.207 8 8H180v-17zm-14.586 17l-7-7h12.865l2.333 7h-8.2zM180 173h-6.613l2.334 7H180v-7zm-21.586-2l5.586-5.586 5.586 5.586h-11.172zM180 165.414L174.414 171H180v-5.586zm-8 5.172l5.586-5.586h-11.172l5.586 5.586zM152.933 25.653l1.414 1.414-33.94 33.942-1.416-1.416 33.943-33.94zm1.414 127.28l-1.414 1.414-33.942-33.94 1.416-1.416 33.94 33.943zm-127.28 1.414l-1.414-1.414 33.94-33.942 1.416 1.416-33.943 33.94zm-1.414-127.28l1.414-1.414 33.942 33.94-1.416 1.416-33.94-33.943zM0 85c2.21 0 4 1.79 4 4s-1.79 4-4 4v-8zm180 0c-2.21 0-4 1.79-4 4s1.79 4 4 4v-8zM94 0c0 2.21-1.79 4-4 4s-4-1.79-4-4h8zm0 180c0-2.21-1.79-4-4-4s-4 1.79-4 4h8z' fill='%23ead0cc' fill-opacity='0.4' fill-rule='evenodd'/%3E%3C/svg%3E");
19+
display: flex;
20+
min-height: 100vh;
21+
align-items: center;
22+
justify-content: center;
23+
24+
}
25+
26+
.voiceinator {
27+
background: white;
28+
width: 50rem;
29+
padding: 2rem;
30+
margin: 0 auto;
31+
overflow: hidden;
32+
border-radius: 1rem;
33+
position: relative;
34+
z-index: 1;
35+
box-shadow: 0 0 5px 5px rgba(0,0,0,0.1);
36+
}
37+
38+
h1 {
39+
width: calc(100% + 4rem);
40+
margin: -2rem 0 2rem -2rem;
41+
padding: .5rem;
42+
background: #52D1DC;
43+
border-bottom: 5px solid #FF715B;
44+
text-align: center;
45+
font-size: 5rem;
46+
font-weight: 100;
47+
font-family: 'Pacifico', cursive;
48+
text-shadow: 3px 3px 0 #eb9689;
49+
}
50+
51+
.voiceinator input, .voiceinator textarea, .voiceinator button, .voiceinator select {
52+
width: 100%;
53+
display: block;
54+
margin: 1rem 0;
55+
padding: 1rem;
56+
border: 0;
57+
font-size: 2rem;
58+
outline: 0;
59+
background: #f7f7f7;
60+
}
61+
62+
textarea {
63+
height: 20rem;
64+
}
65+
66+
label {
67+
font-size: 1.5rem;
68+
}
69+
70+
.voiceinator button {
71+
background: #52D1DC;
72+
width: 49%;
73+
border: 0;
74+
float: left;
75+
font-family: 'Pacifico', cursive;
76+
font-size: 2rem;
77+
margin-bottom: 0;
78+
cursor: pointer;
79+
position: relative;
80+
border-bottom: 5px solid #FF715B;
81+
}
82+
83+
.voiceinator button:active {
84+
top: 2px;
85+
}
86+
87+
.voiceinator button:nth-of-type(1) {
88+
margin-right: 2%;
89+
}
90+
91+
@media (max-width: 55rem) {
92+
.voiceinator {
93+
margin: 0 1.5rem;
94+
}
95+
}

README.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
| 19 | 📷 Webcam Fun | [GitHub][19] | [Link](https://sagarmittal1.github.io/JavaScript30/19-Webcam-Fun/)|
2323
| 20 | 🗣 Speech Detection | [GitHub][20] | [Link](https://sagarmittal1.github.io/JavaScript30/20-Speech-Detection/)|
2424
| 21 | 📌 Geolocation | [GitHub][21] | [Link](https://sagarmittal1.github.io/JavaScript30/21-Geolocation/)|
25-
25+
| 23 | 💬 Speech Synthesis | [GitHub][23] | [Link](https://sagarmittal1.github.io/JavaScript30/23-Speech-Synthesis//)|
2626

2727

2828
[1]: /01-JavaScript-Drum-Kit/
@@ -39,4 +39,5 @@
3939
[16]: /16-Mousemove-Shadow/
4040
[19]: /19-Webcam-Fun/
4141
[20]: /20-Speech-Detection/
42-
[21]: /21-Geolocation/
42+
[21]: /21-Geolocation/
43+
[23]: /23-Speech-Synthesis/

0 commit comments

Comments
 (0)