import {
Button,
FormControl,
Grid,
InputLab
MenuItem,
Select,
TextField,
} from "@mui/material";
import React, { useEffect, useState } from "react";
//
// IMPORT ZONE
//
const Day04 = () => {
const [isPaused, setIsPaused] = useState(false);
const [utterance, setUtterance] = useState(null);
const [voice, setVoice] = useState(null);
const [text, setText] = useState("きゅうりょう どろぼう");
useEffect(() => {
const synth = window.speechSynthesis;
const u = new SpeechSynthesisUtterance(text);
synth.addEventListener("voiceschanged", () => {
const voices = synth.getVoices();
u.voice = voices[0];
setVoice(voices[0]);
});
setUtterance(u);
return () => {
synth.cancel();
synth.removeEventListener("voiceschanged", () => {
setVoice(null);
});
};
}, [text]);
const handleVocieOnChange = (v) => {
setVoice(v.target.value);
};
const handleTextOnChange = (e) => {
setText(e.target.value);
};
const handlePlay = () => {
const synth = window.speechSynthesis;
if (isPaused) {
synth.resume();
} else {
utterance.voice = voice;
synth.speak(utterance);
}
setIsPaused(false);
};
const handlePause = () => {
const synth = window.speechSynthesis;
setIsPaused(true);
synth.pause();
};
return (
<>
<Grid
container
spacing={{ mobile: 1, tablet: 2, laptop: 3 }}
style={{ textAlign: "center" }}
>
<Grid item xs={12}>
<h1> Day 04</h1>
</Grid>
<Grid item xs={12}>
<FormControl fullWidth>
<TextField
label="說話"
value={text}
onChange={(e) => handleTextOnChange(e)}
></TextField>
</FormControl>
<Grid item xs={4}></Grid>
</Grid>
<Grid item xs={12}>
<Grid item xs={4}>
<FormControl fullWidth>
<InputLabel> 選擇說話語音</InputLabel>
<Select
value={voice?.name}
label="選擇說話語音"
onChange={(v) => handleVocieOnChange(v)}
>
{window.speechSynthesis.getVoices().map((voice) => (
<MenuItem key={voice.name} value={voice}>
{voice.name}
</MenuItem>
))}
</Select>
</FormControl>
</Grid>
</Grid>
<Grid container sx={12} spacing={2}>
<Grid item>
<Button variant="contained" onClick={handlePlay}>
{isPaused ? "重播" : "播放"}
</Button>
</Grid>
<Grid item>
<Button variant="contained" color="error" onClick={handlePause}>
暫停
</Button>
</Grid>
</Grid>
</Grid>
</>
);
};
export default Day04;
Day 05 放上 menu
import {
AppBar,
IconButton,
Menu,
MenuItem,
Toolbar,
Typography,
} from "@mui/material";
import React, { useState } from "react";
import MenuIcon from "@mui/icons-material/Menu";
import { AccountCircle } from "@mui/icons-material";
//
// IMPORT ZONE
//
const Day05 = () => {
const [anchorEl, setAnchorEl] = useState(null);
const handleMenuOnclick = (e) => {
setAnchorEl(e.currentTarget);
};
const handleMenuOnClose = () => {
setAnchorEl(null);
};
const go2YutingBlog = () => {
window.open("https://yuting3656.github.io/yutingblog/");
};
return (
<>
<AppBar position="static">
<Toolbar>
<IconButton
size="large"
edge="start"
color="inherit"
aria-label="menu"
sx={{ mr: 2 }}
onClick={(e) => handleMenuOnclick(e)}
>
<MenuIcon />
</IconButton>
<Typography variant="h6" component={"div"} sx={{ flexGrow: 1 }}>
提姆要學 50 音{" "}
</Typography>
<IconButton
size="large"
aria-label="account of current user"
aria-controls="menu-appbar"
aria-haspopup="true"
onClick={() => go2YutingBlog()}
color="inherit"
>
<AccountCircle />
</IconButton>
</Toolbar>
<Menu
anchorEl={anchorEl}
getContentAnchorEl={null}
anchorOrigin={{ vertical: "bottom" }}
keepMounted
open={Boolean(anchorEl)}
onClose={() => handleMenuOnClose()}
>
<MenuItem> Day 01 還</MenuItem>
<MenuItem> Day 02 沒</MenuItem>
<MenuItem> Day 03 有</MenuItem>
<MenuItem> Day 04 用</MenuItem>
<MenuItem> Day 05 拉</MenuItem>
</Menu>
</AppBar>
</>
);
};
export default Day05;
Reference