Web Speech API的SpeechSynthesisUtterance接口代表一个语音请求。它包含语音服务应阅读的内容以及有关如何阅读的信息(例如语言、音高和音量)。–引自MDN
SpeechSynthesisUtterance.lang
获取和设置说话的语言。
SpeechSynthesisUtterance.pitch
获取和设置说话的音调。
SpeechSynthesisUtterance.rate
获取和设置说话的速度。
SpeechSynthesisUtterance.text
获取并设置说话时将合成的文本。
SpeechSynthesisUtterance.voice
获取和设置将用于说语的声音。
SpeechSynthesisUtterance.volume
获取和设置说话的音量。
boundary
当口语达到单词或句子边界时触发。
end
当口语结束时触发
error
当错误发生时触发,该错误导致无法成功说出该语句。
mark
当口语达到指定的SSML“mark”标记时触发。
pause
在说话暂停时触发
resume
当暂停的说话恢复时触发。
start
当开始说话时触发
"container">
Speech Text Reader
"text-box show">
Choose Voice
"close" class="close">X
css代码
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background-color: #ffefea;
min-height: 100vh;
}
.container {
text-align: center;
padding: 20px;
}
h1 {
margin: 20px 0;
}
.btn {
background-color: darksalmon;
color: white;
border-radius: 5px;
font-size: 16px;
padding: 8px;
border: 0 none;
cursor: pointer;
}
.btn:active {
transform: scale(0.98);
}
#toggle {
margin-bottom: 20px;
}
.text-box {
position: absolute;
top: 30%;
left: 50%;
width: 70%;
transform: translateX(-50%);
background-color: #333;
padding: 20px;
border-radius: 5px;
color: white;
transition: all 1s ease-in-out;
}
.close {
float: right;
cursor: pointer;
}
h3 {
float: left;
margin: 18px 0;
}
#voices {
background-color: darksalmon;
height: 30px;
width: 100%;
color: white;
cursor: pointer;
outline: none;
}
#text {
margin: 15px 0;
padding: 8px;
font-size: 16px;
border-radius: 5px;
width: 100%;
height: 150px;
resize: none;
}
#read {
width: 100%;
}
.show {
transform: translate(-50%, -200%);
}
main {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-gap: 10px;
}
.box {
display: flex;
flex-direction: column;
cursor: pointer;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.718);
border-radius: 5px;
overflow: hidden;
}
.box.active {
box-shadow: 0 0 10px 5px darksalmon;
}
.box img {
width: 100%;
height: 200px;
object-fit: cover;
}
.box .info {
background-color: darksalmon;
padding: 10px;
color: white;
font-size: 18px;
}
@media (max-width:1100px) {
main {
grid-template-columns: repeat(3, 1fr);
}
}
@media(max-width:760px) {
main {
grid-template-columns: repeat(2, 1fr);
}
}
@media(max-width:500px) {
main {
grid-template-columns: 1fr;
}
}
js代码
var toggleBtn = document.querySelector('#toggle')
var textbox = document.querySelector('.text-box')
var closeBtn = document.querySelector('#close')
var main = document.querySelector('main')
var readBtn = document.querySelector('#read')
var textarea = document.querySelector('#text')
var voicesSelect = document.querySelector('#voices')
toggleBtn.addEventListener('click', () =>
textbox.classList.toggle('show'))
closeBtn.addEventListener('click', () => {
textbox.classList.toggle('show')
textarea.value = ''
})
var data = [{
image: './img/drink.jpg',
text: "多喝热水"
},
{
image: './img/food.jpg',
text: "不要减肥"
},
{
image: './img/tired.jpg',
text: "多睡觉"
},
{
image: './img/hurt.jpg',
text: "啊哦"
},
{
image: './img/happy.jpg',
text: "病毒快死!"
},
{
image: './img/angry.jpg',
text: "疫情快滚!"
},
{
image: './img/sad.jpg',
text: "烦死人啦!"
},
{
image: './img/scared.jpg',
text: "好想出去玩"
},
{
image: './img/outside.jpg',
text: '世界多好'
},
{
image: './img/home.jpg',
text: '快出去!'
},
{
image: './img/school.jpg',
text: '想回学校!'
},
{
image: './img/grandma.jpg',
text: '呜呜呜'
}
];
data.forEach(createBox)
function createBox(item) {
var box = document.createElement('div')
box.classList.add('box')
var { image, text } = item
box.innerHTML = `${image}" alt="text"/>${text}`
box.addEventListener('click', () => {
setTextMessage(text)
speakText()
box.classList.add('active')
setTimeout(() => {
box.classList.remove('active')
}, 800);
})
main.appendChild(box);
}
var message = new SpeechSynthesisUtterance()
var voices = []
function setTextMessage(text) {
message.text = text
}
function speakText() {
speechSynthesis.speak(message)
}
speechSynthesis.addEventListener('voiceschanged', getVoices)
readBtn.addEventListener('click', () => {
setTextMessage(textarea.value)
speakText()
})
function getVoices() {
voices = speechSynthesis.getVoices()
voices.forEach(voice => {
var options = document.createElement('option')
options.value = voice.name
options.innerHTML = `${voice.name}${voice.lang}`
voicesSelect.appendChild(options)
})
}
voicesSelect.addEventListener('change', function(e) {
message.voice = voices.find(voices => voices.name === e.target.value)
})
写的可能有点乱,都是想到哪写到哪,不会了就去看看人家咋写的了。