feat(all): update audio
This commit is contained in:
1
components.d.ts
vendored
1
components.d.ts
vendored
@@ -44,6 +44,7 @@ declare module 'vue' {
|
||||
TranslateSetting: typeof import('./src/components/Toolbar/TranslateSetting.vue')['default']
|
||||
TypeArticle: typeof import('./src/components/Practice/TypeArticle.vue')['default']
|
||||
TypeWord: typeof import('./src/components/Practice/TypeWord.vue')['default']
|
||||
VolumeIcon: typeof import('./src/components/VolumeIcon.vue')['default']
|
||||
VolumeSetting: typeof import('./src/components/Toolbar/VolumeSetting.vue')['default']
|
||||
WordList: typeof import('./src/components/WordList.vue')['default']
|
||||
}
|
||||
|
||||
BIN
public/sound/beep.wav
Normal file
BIN
public/sound/beep.wav
Normal file
Binary file not shown.
BIN
public/sound/boom.mp3
Normal file
BIN
public/sound/boom.mp3
Normal file
Binary file not shown.
BIN
public/sound/correct.wav
Normal file
BIN
public/sound/correct.wav
Normal file
Binary file not shown.
BIN
public/sound/key-sounds/jixie/机械0.mp3
Normal file
BIN
public/sound/key-sounds/jixie/机械0.mp3
Normal file
Binary file not shown.
BIN
public/sound/key-sounds/jixie/机械1.mp3
Normal file
BIN
public/sound/key-sounds/jixie/机械1.mp3
Normal file
Binary file not shown.
BIN
public/sound/key-sounds/jixie/机械2.mp3
Normal file
BIN
public/sound/key-sounds/jixie/机械2.mp3
Normal file
Binary file not shown.
BIN
public/sound/key-sounds/jixie/机械3.mp3
Normal file
BIN
public/sound/key-sounds/jixie/机械3.mp3
Normal file
Binary file not shown.
BIN
public/sound/key-sounds/快速打字的机械键盘声音.mp3
Normal file
BIN
public/sound/key-sounds/快速打字的机械键盘声音.mp3
Normal file
Binary file not shown.
BIN
public/sound/key-sounds/电话打字的声音.mp3
Normal file
BIN
public/sound/key-sounds/电话打字的声音.mp3
Normal file
Binary file not shown.
BIN
public/sound/key-sounds/老式机械.mp3
Normal file
BIN
public/sound/key-sounds/老式机械.mp3
Normal file
Binary file not shown.
BIN
public/sound/key-sounds/键盘快速打字的声音.mp3
Normal file
BIN
public/sound/key-sounds/键盘快速打字的声音.mp3
Normal file
Binary file not shown.
BIN
public/sound/shotfire.mp3
Normal file
BIN
public/sound/shotfire.mp3
Normal file
Binary file not shown.
@@ -67,7 +67,7 @@ a {
|
||||
outline: none;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 6rem;
|
||||
padding:8rem 10rem;
|
||||
padding: 8rem 10rem;
|
||||
transition: all .3s;
|
||||
min-height: 20rem;
|
||||
width: 100%;
|
||||
@@ -77,7 +77,7 @@ a {
|
||||
border: 1px solid var(--color-main-active);
|
||||
}
|
||||
|
||||
&[readonly]{
|
||||
&[readonly] {
|
||||
cursor: not-allowed;
|
||||
opacity: .7;
|
||||
}
|
||||
@@ -108,11 +108,21 @@ footer {
|
||||
gap: $space;
|
||||
}
|
||||
|
||||
.i-icon {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.flex {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.justify-content-between {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
|
||||
.flex-center {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import {onMounted} from "vue";
|
||||
import {getRandom} from "@/utils/index.ts";
|
||||
import boom from '@/assets/sound/boom.mp3'
|
||||
import shotfire from '@/assets/sound/shotfire.mp3'
|
||||
import {useSound} from "@/hooks/useSound.ts";
|
||||
import {useSound} from "@/hooks/sound.ts";
|
||||
|
||||
const canvas = $ref()
|
||||
const [playBoom] = useSound([boom], 3)
|
||||
|
||||
@@ -15,7 +15,7 @@ export default {
|
||||
<style scoped lang="scss">
|
||||
@import "@/assets/css/colors";
|
||||
|
||||
$w: 20rem;
|
||||
$w: 22rem;
|
||||
.icon-wrapper {
|
||||
//padding: 2rem;
|
||||
width: 26rem;
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
<script setup lang="ts">
|
||||
interface IProps {
|
||||
modelValue?: boolean,
|
||||
width?: string
|
||||
}
|
||||
|
||||
withDefaults(defineProps<IProps>(), {
|
||||
modelValue: true,
|
||||
width: '180rem'
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Transition name="fade">
|
||||
<div v-if="modelValue" class="mini-modal">
|
||||
<div v-if="modelValue" class="mini-modal" :style="{width}">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</Transition>
|
||||
|
||||
@@ -1,41 +1,13 @@
|
||||
<script setup lang="ts">
|
||||
import {Icon} from '@iconify/vue'
|
||||
import {usePlayWordAudio} from "@/hooks/usePlayWordAudio.ts"
|
||||
import {computed, nextTick, onMounted, reactive, watch, watchEffect} from "vue"
|
||||
import {cloneDeep} from "lodash-es"
|
||||
import 快速打字的机械键盘声音Mp3 from '../..//assets/sound/key-sounds/快速打字的机械键盘声音.mp3'
|
||||
import 键盘快速打字的声音Mp3 from '../..//assets/sound/key-sounds/键盘快速打字的声音.mp3'
|
||||
import 电话打字的声音Mp3 from '../..//assets/sound/key-sounds/电话打字的声音.mp3'
|
||||
import 老式机械 from '../..//assets/sound/key-sounds/老式机械.mp3'
|
||||
import 机械0 from '../..//assets/sound/key-sounds/jixie/机械0.mp3'
|
||||
import 机械1 from '../..//assets/sound/key-sounds/jixie/机械1.mp3'
|
||||
import 机械2 from '../..//assets/sound/key-sounds/jixie/机械2.mp3'
|
||||
import 机械3 from '../..//assets/sound/key-sounds/jixie/机械3.mp3'
|
||||
import beep from '../..//assets/sound/beep.wav'
|
||||
import correct from '../..//assets/sound/correct.wav'
|
||||
import {useSound} from "@/hooks/useSound.ts"
|
||||
import {$computed, $ref} from "vue/macros";
|
||||
import {
|
||||
Article,
|
||||
ArticleWord,
|
||||
DefaultWord,
|
||||
DictType,
|
||||
SaveKey,
|
||||
Sentence,
|
||||
ShortKeyMap,
|
||||
TranslateEngine,
|
||||
Word
|
||||
} from "@/types";
|
||||
import {computed, nextTick, watchEffect} from "vue"
|
||||
import {$ref} from "vue/macros";
|
||||
import {Article, ArticleWord, ShortKeyMap, Word} from "@/types";
|
||||
import {useBaseStore} from "@/stores/base";
|
||||
import {usePracticeStore} from "@/components/Practice/usePracticeStore.ts";
|
||||
import {useEventListener} from "@/hooks/useEvent.ts";
|
||||
import TypeWord from "@/components/Practice/TypeWord.vue";
|
||||
import {updateLocalSentenceTranslate, getNetworkTranslate} from "@/hooks/translate.ts";
|
||||
import IconWrapper from "@/components/IconWrapper.vue";
|
||||
import Tooltip from "@/components/Tooltip.vue";
|
||||
import MiniModal from "@/components/MiniModal.vue";
|
||||
import {splitArticle} from "@/hooks/article.ts";
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
import {usePlayBeep, usePlayCorrect, usePlayKeyboardAudio, usePlayWordAudio} from "@/hooks/sound.ts";
|
||||
|
||||
let article1 = `How does the older investor differ in his approach to investment from the younger investor?
|
||||
There is no shortage of tipsters around offering 'get-rich-quick' opportunities. But if you are a serious private investor, leave the Las Vegas mentality to those with money to fritter. The serious investor needs a proper 'portfolio' -- a well-planned selection of investments, with a definite structure and a clear aim. But exactly how does a newcomer to the stock market go about achieving that?
|
||||
@@ -51,13 +23,10 @@ article1 = `Last week I went to the theatre. I had a very good seat. The play wa
|
||||
‘It's none of your business, ’ the young man said rudely. ‘This is a private conversation!’`
|
||||
// article1 = `Last week I went to the theatre. I had a very good seat. The play was very interesting. I did not enjoy it.`
|
||||
|
||||
const [playAudio] = usePlayWordAudio()
|
||||
// const [playKeySound, setAudio] = useSound([机械0, 机械1, 机械2, 机械3], 1)
|
||||
const [playKeySound, setAudio] = useSound([老式机械], 3)
|
||||
// const [playKeySound, setAudio] = useSound([电话打字的声音Mp3], 3)
|
||||
const [playBeep] = useSound([beep], 1)
|
||||
const [playCorrect] = useSound([correct], 1)
|
||||
|
||||
const playBeep = usePlayBeep()
|
||||
const playCorrect = usePlayCorrect()
|
||||
const playKeyboardAudio = usePlayKeyboardAudio()
|
||||
const playWordAudio = usePlayWordAudio()
|
||||
const store = useBaseStore()
|
||||
const practiceStore = usePracticeStore()
|
||||
const settingStore = useSettingStore()
|
||||
@@ -159,7 +128,7 @@ function calcTranslateLocation() {
|
||||
}
|
||||
|
||||
function play() {
|
||||
return playAudio(article1)
|
||||
return playWordAudio(article1)
|
||||
if (isPlay) {
|
||||
isPlay = false
|
||||
return window.speechSynthesis.pause();
|
||||
@@ -205,7 +174,7 @@ function onKeyDown(e: KeyboardEvent) {
|
||||
if (settingStore.dictation) {
|
||||
calcTranslateLocation()
|
||||
}
|
||||
playAudio(currentSection[sentenceIndex].text)
|
||||
playWordAudio(currentSection[sentenceIndex].text)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -237,7 +206,7 @@ function onKeyDown(e: KeyboardEvent) {
|
||||
wrong = input = ''
|
||||
}, 500)
|
||||
}
|
||||
playKeySound()
|
||||
playKeyboardAudio()
|
||||
} else {
|
||||
let letter = e.key
|
||||
|
||||
@@ -288,7 +257,7 @@ function onKeyDown(e: KeyboardEvent) {
|
||||
}, 500)
|
||||
// console.log('未匹配')
|
||||
}
|
||||
playKeySound()
|
||||
playKeyboardAudio()
|
||||
}
|
||||
} else {
|
||||
switch (e.key) {
|
||||
@@ -335,11 +304,9 @@ function onKeyUp() {
|
||||
}
|
||||
}
|
||||
|
||||
useEventListener('keydown', onKeyDown)
|
||||
useEventListener('keyup', onKeyUp)
|
||||
|
||||
function playWord(word: ArticleWord) {
|
||||
playAudio(word.name)
|
||||
playWordAudio(word.name)
|
||||
}
|
||||
|
||||
function currentWordInput(word: ArticleWord, i: number, i2: number,) {
|
||||
@@ -388,6 +355,8 @@ function otherWord(word: ArticleWord, i: number, i2: number, i3: number) {
|
||||
return str
|
||||
}
|
||||
|
||||
useEventListener('keydown', onKeyDown)
|
||||
useEventListener('keyup', onKeyUp)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -410,7 +379,7 @@ function otherWord(word: ArticleWord, i: number, i2: number, i3: number) {
|
||||
]"
|
||||
@mouseenter="settingStore.allowWordTip && (hoverIndex = {sectionIndex : indexI,sentenceIndex :indexJ})"
|
||||
@mouseleave="hoverIndex = {sectionIndex : -1,sentenceIndex :-1}"
|
||||
@click="playAudio(sentence.text)"
|
||||
@click="playWordAudio(sentence.text)"
|
||||
v-for="(sentence,indexJ) in section">
|
||||
<span
|
||||
v-for="(word,indexW) in sentence.words"
|
||||
|
||||
@@ -1,28 +1,15 @@
|
||||
<script setup lang="ts">
|
||||
import {computed, onMounted, onUnmounted, provide, watch, watchEffect} from "vue"
|
||||
import 快速打字的机械键盘声音Mp3 from '../../assets/sound/key-sounds/快速打字的机械键盘声音.mp3'
|
||||
import 键盘快速打字的声音Mp3 from '../../assets/sound/key-sounds/键盘快速打字的声音.mp3'
|
||||
import 电话打字的声音Mp3 from '../../assets/sound/key-sounds/电话打字的声音.mp3'
|
||||
import 老式机械 from '../../assets/sound/key-sounds/老式机械.mp3'
|
||||
import 机械0 from '../../assets/sound/key-sounds/jixie/机械0.mp3'
|
||||
import 机械1 from '../../assets/sound/key-sounds/jixie/机械1.mp3'
|
||||
import 机械2 from '../../assets/sound/key-sounds/jixie/机械2.mp3'
|
||||
import 机械3 from '../../assets/sound/key-sounds/jixie/机械3.mp3'
|
||||
import beep from '../../assets/sound/beep.wav'
|
||||
import correct from '../../assets/sound/correct.wav'
|
||||
import {onMounted, watchEffect} from "vue"
|
||||
import {$computed, $ref} from "vue/macros"
|
||||
import {useSound} from "@/hooks/useSound.ts"
|
||||
import {useBaseStore} from "@/stores/base.ts"
|
||||
import {DictType, SaveKey, ShortKeyMap, Statistics, Word} from "../../types";
|
||||
import {usePlayWordAudio} from "@/hooks/usePlayWordAudio.ts"
|
||||
import useTheme from "@/hooks/useTheme.ts";
|
||||
import Tooltip from "@/components/Tooltip.vue";
|
||||
import {DictType, ShortKeyMap, Word} from "../../types";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import {emitter, EventKey} from "@/utils/eventBus.ts"
|
||||
import {cloneDeep} from "lodash-es"
|
||||
import {usePracticeStore} from "@/components/Practice/usePracticeStore.ts"
|
||||
import {useEventListener} from "@/hooks/useEvent.ts";
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
import {usePlayBeep, usePlayCorrect, usePlayKeyboardAudio, usePlayWordAudio} from "@/hooks/sound.ts";
|
||||
|
||||
interface IProps {
|
||||
words: Word[],
|
||||
@@ -50,12 +37,10 @@ const store = useBaseStore()
|
||||
const practiceStore = usePracticeStore()
|
||||
const settingStore = useSettingStore()
|
||||
|
||||
// const [playKeySound, setAudio] = useSound([机械0, 机械1, 机械2, 机械3], 1)
|
||||
// const [playKeySound, setAudio] = useSound([老式机械], 3)
|
||||
const [playKeySound, setAudio] = useSound([电话打字的声音Mp3], 3)
|
||||
const [playBeep] = useSound([beep], 1)
|
||||
const [playCorrect] = useSound([correct], 1)
|
||||
const [playAudio] = usePlayWordAudio()
|
||||
const playBeep = usePlayBeep()
|
||||
const playCorrect = usePlayCorrect()
|
||||
const playKeyboardAudio = usePlayKeyboardAudio()
|
||||
const playWordAudio = usePlayWordAudio()
|
||||
|
||||
|
||||
watchEffect(() => {
|
||||
@@ -140,7 +125,7 @@ async function onKeyDown(e: KeyboardEvent) {
|
||||
if (isWrong) {
|
||||
input += letter
|
||||
wrong = ''
|
||||
playKeySound()
|
||||
playKeyboardAudio()
|
||||
} else {
|
||||
if (!store.wrongWordDict.originWords.find((v: Word) => v.name.toLowerCase() === word.name.toLowerCase())) {
|
||||
store.wrongWordDict.originWords.push(word)
|
||||
@@ -152,7 +137,7 @@ async function onKeyDown(e: KeyboardEvent) {
|
||||
practiceStore.wrongNumber++
|
||||
}
|
||||
wrong = letter
|
||||
playKeySound()
|
||||
playKeyboardAudio()
|
||||
playBeep()
|
||||
setTimeout(() => {
|
||||
wrong = ''
|
||||
@@ -229,7 +214,7 @@ async function onKeyDown(e: KeyboardEvent) {
|
||||
</template>
|
||||
<span class="letter" v-else>{{ resetWord }}</span>
|
||||
</div>
|
||||
<div class="audio" @click="playAudio(word.name)">播放</div>
|
||||
<div class="audio" @click="playWordAudio(word.name)">播放</div>
|
||||
</div>
|
||||
<div class="phonetic">{{ word.usphone }}</div>
|
||||
<div class="options">
|
||||
|
||||
@@ -4,6 +4,7 @@ import {useBaseStore} from "@/stores/base.ts"
|
||||
import {Icon} from '@iconify/vue';
|
||||
import {watch, ref} from "vue";
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
import {useChangeAllSound, useWatchAllSound} from "@/hooks/sound.ts";
|
||||
|
||||
const tabIndex = $ref(0)
|
||||
const settingStore = useSettingStore()
|
||||
@@ -20,28 +21,7 @@ const emit = defineEmits([
|
||||
'update:modelValue',
|
||||
])
|
||||
|
||||
let allSound = $ref<boolean>(true)
|
||||
|
||||
watch([
|
||||
() => settingStore.wordSound,
|
||||
() => settingStore.keyboardSound,
|
||||
() => settingStore.translateSound,
|
||||
() => settingStore.effectSound,
|
||||
], (n) => {
|
||||
if (n.some(v => v)) {
|
||||
allSound = true
|
||||
} else {
|
||||
allSound = false
|
||||
}
|
||||
})
|
||||
|
||||
function changAllSound(e: boolean) {
|
||||
allSound = e
|
||||
settingStore.wordSound = e
|
||||
settingStore.keyboardSound = e
|
||||
settingStore.translateSound = e
|
||||
settingStore.effectSound = e
|
||||
}
|
||||
useWatchAllSound()
|
||||
|
||||
</script>
|
||||
|
||||
@@ -66,8 +46,8 @@ function changAllSound(e: boolean) {
|
||||
<div class="row">
|
||||
<label class="main-title">所有音效</label>
|
||||
<div class="wrapper">
|
||||
<el-switch v-model="allSound"
|
||||
@change="changAllSound"
|
||||
<el-switch v-model="settingStore.allSound"
|
||||
@change="useChangeAllSound"
|
||||
inline-prompt
|
||||
active-text="开"
|
||||
inactive-text="关"
|
||||
|
||||
@@ -4,34 +4,54 @@ import MiniModal from "@/components/MiniModal.vue";
|
||||
import {Icon} from "@iconify/vue";
|
||||
import IconWrapper from "@/components/IconWrapper.vue";
|
||||
import Tooltip from "@/components/Tooltip.vue";
|
||||
import {useBaseStore} from "@/stores/base.ts";
|
||||
import {useWindowClick} from "@/hooks/event.ts";
|
||||
import {emitter, EventKey} from "@/utils/eventBus.ts";
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
import VolumeIcon from "@/components/VolumeIcon.vue";
|
||||
import {getAudioFileUrl, useChangeAllSound, usePlayAudio, useWatchAllSound} from "@/hooks/sound.ts";
|
||||
import {SoundFileOptions} from "@/utils/const.ts";
|
||||
|
||||
const store = useBaseStore()
|
||||
const settingStore = useSettingStore()
|
||||
|
||||
let show = $ref(false)
|
||||
|
||||
useWindowClick(() => show = false)
|
||||
useWatchAllSound()
|
||||
|
||||
function toggle() {
|
||||
if (!show) emitter.emit(EventKey.closeOther)
|
||||
show = !show
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="setting" @click.stop="null">
|
||||
<div class="setting"
|
||||
@click.stop="null">
|
||||
<Tooltip title="音效设置">
|
||||
<IconWrapper>
|
||||
<Icon icon="icon-park-outline:volume-notice"
|
||||
<Icon v-if="settingStore.allSound" icon="icon-park-outline:volume-notice"
|
||||
@click="toggle"
|
||||
/>
|
||||
<Icon v-else icon="icon-park-outline:volume-mute"
|
||||
@click="toggle"
|
||||
/>
|
||||
</IconWrapper>
|
||||
</Tooltip>
|
||||
<MiniModal v-model="show">
|
||||
<MiniModal
|
||||
width="230rem"
|
||||
v-model="show">
|
||||
<div class="mini-row">
|
||||
<label class="item-title">所有音效</label>
|
||||
<div class="wrapper">
|
||||
<el-switch v-model="settingStore.allSound"
|
||||
@change="useChangeAllSound"
|
||||
inline-prompt
|
||||
active-text="开"
|
||||
inactive-text="关"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mini-row">
|
||||
<label class="item-title">单词发音</label>
|
||||
<div class="wrapper">
|
||||
@@ -62,6 +82,28 @@ function toggle() {
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mini-row">
|
||||
<label class="item-title">按键音效</label>
|
||||
<div class="wrapper">
|
||||
<el-select v-model="settingStore.keyboardSoundFile"
|
||||
placeholder="请选择"
|
||||
size="small">
|
||||
<el-option
|
||||
v-for="item in SoundFileOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
>
|
||||
<div class="el-option-row">
|
||||
<span>{{ item.label }}</span>
|
||||
<VolumeIcon
|
||||
:time="100"
|
||||
@click="usePlayAudio(getAudioFileUrl(item.value)[0])"/>
|
||||
</div>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mini-row">
|
||||
<label class="item-title">效果音</label>
|
||||
<div class="wrapper">
|
||||
@@ -85,6 +127,16 @@ function toggle() {
|
||||
|
||||
.setting {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.el-option-row {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.icon-wrapper {
|
||||
transform: translateX(10rem);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
49
src/components/VolumeIcon.vue
Normal file
49
src/components/VolumeIcon.vue
Normal file
@@ -0,0 +1,49 @@
|
||||
<script setup lang="ts">
|
||||
import {Icon} from "@iconify/vue";
|
||||
import {$ref} from "vue/macros";
|
||||
import IconWrapper from "@/components/IconWrapper.vue";
|
||||
|
||||
const props = withDefaults(defineProps<{ time?: number }>(), {
|
||||
time: 400
|
||||
})
|
||||
let step = $ref(0)
|
||||
const emit = defineEmits(['click'])
|
||||
|
||||
function play(time = props.time) {
|
||||
setTimeout(() => {
|
||||
if (step === 2) {
|
||||
step = 0
|
||||
} else {
|
||||
step++
|
||||
if (step === 2) {
|
||||
play(time + 100)
|
||||
} else {
|
||||
play(time + 100)
|
||||
}
|
||||
}
|
||||
}, time)
|
||||
}
|
||||
|
||||
function click() {
|
||||
emit('click')
|
||||
play()
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<IconWrapper @click.stop="click">
|
||||
<div class="center">
|
||||
<Icon v-if="step === 0" icon="bx:volume"/>
|
||||
<Icon v-if="step === 1" icon="bx:volume-low"/>
|
||||
<Icon v-if="step === 2" icon="bx:volume-full"/>
|
||||
</div>
|
||||
</IconWrapper>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.center {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
</style>
|
||||
@@ -1,9 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
import {Word} from "../types";
|
||||
import {usePlayWordAudio} from "../hooks/usePlayWordAudio";
|
||||
import {watch} from "vue"
|
||||
import {useBaseStore} from "@/stores/base.ts"
|
||||
import {Icon} from '@iconify/vue';
|
||||
import {usePlayWordAudio} from "@/hooks/sound.ts";
|
||||
|
||||
const store = useBaseStore()
|
||||
const emit = defineEmits(['change'])
|
||||
@@ -13,7 +13,7 @@ const props = defineProps<{
|
||||
isActive: boolean
|
||||
}>()
|
||||
|
||||
const [playAudio] = usePlayWordAudio()
|
||||
const playWordAudio = usePlayWordAudio()
|
||||
const listRef: HTMLElement = $ref(null as any)
|
||||
|
||||
function scrollViewToCenter(index: number) {
|
||||
@@ -52,7 +52,7 @@ watch(() => props.list, () => {
|
||||
</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<div class="audio" @click="playAudio(item.name)">播放</div>
|
||||
<div class="audio" @click="playWordAudio(item.name)">播放</div>
|
||||
<Icon icon="fluent:delete-28-regular" width="20" color="#929596"/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -93,7 +93,7 @@ watch(() => props.list, () => {
|
||||
&:hover {
|
||||
//background: $dark-main-bg;
|
||||
//background: $item-hover;
|
||||
background: rgb(226,226,226);
|
||||
background: rgb(226, 226, 226);
|
||||
}
|
||||
|
||||
.left {
|
||||
|
||||
@@ -1,42 +1,118 @@
|
||||
import {onMounted} from "vue"
|
||||
import {useBaseStore} from "@/stores/base.ts";
|
||||
import {onMounted, watch, watchEffect} from "vue"
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
import {PronunciationApi} from "@/types.ts";
|
||||
import beep from "@/assets/sound/beep.wav";
|
||||
import correct from "@/assets/sound/correct.wav";
|
||||
|
||||
export function useSound(srcList?: string[], num?: number) {
|
||||
let audioList: HTMLAudioElement[] = $ref([])
|
||||
let audioLength = $ref(1)
|
||||
const setAudio = (srcList2: string[], num2?: number) => {
|
||||
if (num2) audioLength = num2
|
||||
audioList = []
|
||||
for (let i = 0; i < audioLength; i++) {
|
||||
srcList2.map(src => {
|
||||
audioList.push(new Audio(src))
|
||||
})
|
||||
export function useSound(urlList?: string[], num?: number) {
|
||||
let audioList: HTMLAudioElement[] = $ref([])
|
||||
let audioLength = $ref(1)
|
||||
let index = $ref(0)
|
||||
|
||||
onMounted(() => {
|
||||
if (urlList) setAudio(urlList, num)
|
||||
})
|
||||
|
||||
function setAudio(srcList2: string[], num2?: number) {
|
||||
if (num2) audioLength = num2
|
||||
audioList = []
|
||||
for (let i = 0; i < audioLength; i++) {
|
||||
srcList2.map(src => audioList.push(new Audio(src)))
|
||||
}
|
||||
index = 0
|
||||
}
|
||||
index = 0
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (srcList) setAudio(srcList, num)
|
||||
})
|
||||
function play() {
|
||||
index++
|
||||
if (audioList.length > 1 && audioList.length !== audioLength) {
|
||||
audioList[index % audioList.length].play()
|
||||
} else {
|
||||
audioList[index % audioLength].play()
|
||||
}
|
||||
}
|
||||
|
||||
let index = $ref(0)
|
||||
const play: Function = () => {
|
||||
index++
|
||||
if (audioList.length > 1 && audioList.length !== audioLength) {
|
||||
audioList[index % audioList.length].play()
|
||||
return [
|
||||
play,
|
||||
setAudio
|
||||
]
|
||||
}
|
||||
|
||||
export function usePlayKeyboardAudio() {
|
||||
const settingStore = useSettingStore()
|
||||
const [playKeyboardAudio, setAudio] = useSound()
|
||||
|
||||
watchEffect(() => {
|
||||
let urlList = getAudioFileUrl(settingStore.keyboardSoundFile)
|
||||
setAudio(urlList, urlList.length === 1 ? 3 : 1)
|
||||
})
|
||||
return playKeyboardAudio
|
||||
}
|
||||
|
||||
export function usePlayBeep() {
|
||||
return useSound([beep], 1)[0]
|
||||
}
|
||||
|
||||
export function usePlayCorrect() {
|
||||
return useSound([correct], 1)[0]
|
||||
}
|
||||
|
||||
export function usePlayWordAudio() {
|
||||
const audio = $ref(new Audio())
|
||||
|
||||
function generateWordSoundSrc(word: string, pronunciation: string) {
|
||||
switch (pronunciation) {
|
||||
case 'uk':
|
||||
return `${PronunciationApi}${word}&type=1`
|
||||
case 'us':
|
||||
return `${PronunciationApi}${word}&type=2`
|
||||
}
|
||||
}
|
||||
|
||||
function playWordAudio(word: string) {
|
||||
audio.src = generateWordSoundSrc(word, 'us')
|
||||
audio.play()
|
||||
}
|
||||
|
||||
return playWordAudio
|
||||
}
|
||||
|
||||
export function usePlayAudio(url: string) {
|
||||
new Audio(url).play().then(r => void 0)
|
||||
}
|
||||
|
||||
export function getAudioFileUrl(name: string) {
|
||||
if (name === '机械') {
|
||||
return [
|
||||
`/sound/key-sounds/jixie/机械0.mp3`,
|
||||
`/sound/key-sounds/jixie/机械1.mp3`,
|
||||
`/sound/key-sounds/jixie/机械2.mp3`,
|
||||
`/sound/key-sounds/jixie/机械3.mp3`,
|
||||
]
|
||||
} else {
|
||||
audioList[index % audioLength].play()
|
||||
return [`/sound/key-sounds/${name}.mp3`]
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
play,
|
||||
setAudio
|
||||
]
|
||||
}
|
||||
|
||||
export function playKeyboardSound() {
|
||||
const store = useBaseStore()
|
||||
|
||||
export function useWatchAllSound() {
|
||||
const settingStore = useSettingStore()
|
||||
|
||||
watch([
|
||||
() => settingStore.wordSound,
|
||||
() => settingStore.keyboardSound,
|
||||
() => settingStore.translateSound,
|
||||
() => settingStore.effectSound,
|
||||
], (n) => {
|
||||
settingStore.allSound = n.some(v => v);
|
||||
})
|
||||
}
|
||||
|
||||
export function useChangeAllSound(e: boolean) {
|
||||
const settingStore = useSettingStore()
|
||||
|
||||
settingStore.allSound = e
|
||||
settingStore.wordSound = e
|
||||
settingStore.keyboardSound = e
|
||||
settingStore.translateSound = e
|
||||
settingStore.effectSound = e
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import {PronunciationApi} from "../types";
|
||||
|
||||
export function usePlayWordAudio() {
|
||||
const audio = $ref(new Audio())
|
||||
|
||||
function generateWordSoundSrc(word: string, pronunciation: string) {
|
||||
switch (pronunciation) {
|
||||
case 'uk':
|
||||
return `${PronunciationApi}${word}&type=1`
|
||||
case 'us':
|
||||
return `${PronunciationApi}${word}&type=2`
|
||||
}
|
||||
}
|
||||
|
||||
function playAudio(word: string) {
|
||||
audio.src = generateWordSoundSrc(word, 'us')
|
||||
audio.play()
|
||||
}
|
||||
|
||||
return [playAudio]
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
import {onMounted} from "vue"
|
||||
|
||||
export function useSound(srcList?: string[], num?: number) {
|
||||
let audioList: HTMLAudioElement[] = $ref([])
|
||||
let audioLength = $ref(1)
|
||||
const setAudio = (srcList2: string[], num2?: number) => {
|
||||
if (num2) audioLength = num2
|
||||
audioList = []
|
||||
for (let i = 0; i < audioLength; i++) {
|
||||
srcList2.map(src => {
|
||||
audioList.push(new Audio(src))
|
||||
})
|
||||
}
|
||||
index = 0
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (srcList) setAudio(srcList, num)
|
||||
})
|
||||
|
||||
let index = $ref(0)
|
||||
const play: Function = () => {
|
||||
index++
|
||||
if (audioList.length > 1 && audioList.length !== audioLength) {
|
||||
audioList[index % audioList.length].play()
|
||||
} else {
|
||||
audioList[index % audioLength].play()
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
play,
|
||||
setAudio
|
||||
]
|
||||
}
|
||||
@@ -4,6 +4,7 @@ export interface SettingState {
|
||||
showToolbar: boolean,
|
||||
show: boolean,
|
||||
|
||||
allSound: boolean,
|
||||
wordSound: boolean,
|
||||
wordSoundVolume: number,
|
||||
wordSoundSpeed: number,
|
||||
@@ -25,10 +26,6 @@ export interface SettingState {
|
||||
foreignLanguageFontSize: number,
|
||||
translateLanguageFontSize: number,
|
||||
|
||||
value1: boolean,
|
||||
value2: number,
|
||||
value3: number,
|
||||
value4: boolean,
|
||||
}
|
||||
|
||||
export const useSettingStore = defineStore('setting', {
|
||||
@@ -37,12 +34,13 @@ export const useSettingStore = defineStore('setting', {
|
||||
showToolbar: true,
|
||||
show: false,
|
||||
|
||||
allSound: true,
|
||||
wordSound: true,
|
||||
wordSoundVolume: 100,
|
||||
wordSoundSpeed: 1,
|
||||
keyboardSound: true,
|
||||
keyboardSoundVolume: 100,
|
||||
keyboardSoundFile: '老式机械.mp3',
|
||||
keyboardSoundFile: '老式机械',
|
||||
translateSound: true,
|
||||
translateSoundVolume: 100,
|
||||
effectSound: true,
|
||||
@@ -59,10 +57,6 @@ export const useSettingStore = defineStore('setting', {
|
||||
translateLanguageFontSize: 20,
|
||||
waitTimeForChangeWord: 300,
|
||||
|
||||
value1: false,
|
||||
value2: 50,
|
||||
value3: 1,
|
||||
value4: false,
|
||||
}
|
||||
},
|
||||
})
|
||||
7
src/utils/const.ts
Normal file
7
src/utils/const.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export const SoundFileOptions = [
|
||||
{value: '快速打字的机械键盘声音', label: '快速打字的机械键盘声音'},
|
||||
{value: '键盘快速打字的声音', label: '键盘快速打字的声音'},
|
||||
{value: '电话打字的声音', label: '电话打字的声音'},
|
||||
{value: '老式机械', label: '老式机械'},
|
||||
{value: '机械', label: '机械'},
|
||||
]
|
||||
Reference in New Issue
Block a user