Skip to content

Commit 674cfa6

Browse files
committed
Adding Day AsmrProg-YT#19
1 parent e10fa0d commit 674cfa6

File tree

3 files changed

+217
-0
lines changed

3 files changed

+217
-0
lines changed
Lines changed: 35 additions & 0 deletions
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+
<link rel="stylesheet" href="style.css">
9+
<title>Day #19 - Text To Speech App | AsmrProg</title>
10+
</head>
11+
12+
<body>
13+
14+
<div class="wrapper">
15+
<header>Text To Speech</header>
16+
<form action="">
17+
<div class="row">
18+
<label>Enter Text</label>
19+
<textarea></textarea>
20+
</div>
21+
<div class="row">
22+
<label>Select Voice</label>
23+
<div class="outer">
24+
<select></select>
25+
</div>
26+
</div>
27+
<button>Convert To Speech</button>
28+
</form>
29+
</div>
30+
31+
32+
<script src="index.js"></script>
33+
</body>
34+
35+
</html>
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
const textarea = document.querySelector("textarea"),
2+
voiceList = document.querySelector("select"),
3+
speechBtn = document.querySelector("button");
4+
5+
let synth = speechSynthesis,
6+
isSpeaking = true;
7+
8+
voices();
9+
10+
function voices() {
11+
for (let voice of synth.getVoices()) {
12+
let selected = voice.name === "Google US English" ? "selected" : "";
13+
let option = `<option value="${voice.name}" ${selected}>${voice.name} (${voice.lang})</option>`;
14+
voiceList.insertAdjacentHTML("beforeend", option);
15+
}
16+
}
17+
18+
synth.addEventListener("voiceschanged", voices);
19+
20+
function textToSpeech(text) {
21+
let utterance = new SpeechSynthesisUtterance(text);
22+
for (let voice of synth.getVoices()) {
23+
if (voice.name === voiceList.value) {
24+
utterance.voice = voice;
25+
}
26+
}
27+
synth.speak(utterance);
28+
}
29+
30+
speechBtn.addEventListener("click", e => {
31+
e.preventDefault();
32+
if (textarea.value !== "") {
33+
// Checks if not speaking, Speak Textarea Text
34+
if (!synth.speaking) {
35+
textToSpeech(textarea.value);
36+
}
37+
// If text was long, Add Resume and Pause Function
38+
if (textarea.value.length > 80) {
39+
setInterval(() => {
40+
if (!synth.speaking && !isSpeaking) {
41+
isSpeaking = true;
42+
speechBtn.innerText = "Convert To Speech";
43+
} else { }
44+
}, 500);
45+
if (isSpeaking) {
46+
synth.resume();
47+
isSpeaking = false;
48+
speechBtn.innerText = "Pause Speech";
49+
} else {
50+
synth.pause();
51+
isSpeaking = true;
52+
speechBtn.innerText = "Resume Speech";
53+
}
54+
} else {
55+
speechBtn.innerText = "Convert To Speech";
56+
}
57+
}
58+
});
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700;800&display=swap');
2+
3+
*{
4+
margin: 0;
5+
padding: 0;
6+
box-sizing: border-box;
7+
font-family: 'Poppins', sans-serif;
8+
}
9+
10+
body{
11+
display: flex;
12+
align-items: center;
13+
justify-content: center;
14+
min-height: 100vh;
15+
background-color: #5256ad;
16+
}
17+
18+
::selection{
19+
color: #fff;
20+
background-color: #5256ad;
21+
}
22+
23+
.wrapper{
24+
width: 370px;
25+
padding: 25px 30px;
26+
border-radius: 7px;
27+
background-color: #fff;
28+
box-shadow: 7px 7px 20px rgba(0, 0, 0, 0.05);
29+
}
30+
31+
.wrapper header{
32+
font-size: 28px;
33+
font-weight: 500;
34+
text-align: center;
35+
}
36+
37+
.wrapper form{
38+
margin: 35px 0 20px;
39+
}
40+
41+
form .row{
42+
display: flex;
43+
margin-bottom: 20px;
44+
flex-direction: column;
45+
}
46+
47+
form .row label{
48+
font-size: 18px;
49+
margin-bottom: 5px;
50+
}
51+
52+
form .row:nth-child(2) label{
53+
font-size: 17px;
54+
}
55+
56+
form :where(textarea, select, button){
57+
outline: none;
58+
width: 100%;
59+
height: 100%;
60+
border: none;
61+
border-radius: 5px;
62+
}
63+
64+
form .row textarea{
65+
resize: none;
66+
height: 110px;
67+
font-size: 15px;
68+
padding: 8px 10px;
69+
border: 1px solid #999;
70+
}
71+
72+
form .row textarea::-webkit-scrollbar{
73+
width: 0px;
74+
}
75+
76+
form .row .outer{
77+
height: 47px;
78+
display: flex;
79+
padding: 0 10px;
80+
align-items: center;
81+
border-radius: 5px;
82+
justify-content: center;
83+
border: 1px solid #999;
84+
}
85+
86+
form .row select{
87+
font-size: 14px;
88+
background: none;
89+
}
90+
91+
form .row select::-webkit-scrollbar{
92+
width: 8px;
93+
}
94+
95+
form .row select::-webkit-scrollbar-track{
96+
background: #fff;
97+
}
98+
99+
form .row select::-webkit-scrollbar-thumb{
100+
background-color: #888;
101+
border-radius: 8px;
102+
border-right: 2px solid #fff;
103+
}
104+
105+
form button{
106+
height: 52px;
107+
color: #fff;
108+
font-size: 17px;
109+
background-color: #675afe;
110+
cursor: pointer;
111+
margin-top: 10px;
112+
transition: 0.3s ease;
113+
}
114+
115+
form button:hover{
116+
background-color: #4534fe;
117+
}
118+
119+
@media(max-width: 400px) {
120+
.wrapper{
121+
max-width: 345px;
122+
width: 100%;
123+
}
124+
}

0 commit comments

Comments
 (0)