|
@@ -1,4 +1,4 @@
|
|
-import { defineComponent, reactive } from "vue";
|
|
|
|
|
|
+import { defineComponent, reactive, onMounted } from "vue";
|
|
import tockAndTick from "/src/constant/tockAndTick.json";
|
|
import tockAndTick from "/src/constant/tockAndTick.json";
|
|
import { Howl } from "howler";
|
|
import { Howl } from "howler";
|
|
import { Popup } from "vant";
|
|
import { Popup } from "vant";
|
|
@@ -20,7 +20,7 @@ export const tickData = reactive({
|
|
show: false,
|
|
show: false,
|
|
});
|
|
});
|
|
|
|
|
|
-const handlePlay = (i: number, source: Howl | null) => {
|
|
|
|
|
|
+const handlePlay = (i: number, source: any | null) => {
|
|
return new Promise((resolve) => {
|
|
return new Promise((resolve) => {
|
|
setTimeout(() => {
|
|
setTimeout(() => {
|
|
if (tickData.tickEnd) {
|
|
if (tickData.tickEnd) {
|
|
@@ -34,6 +34,25 @@ const handlePlay = (i: number, source: Howl | null) => {
|
|
});
|
|
});
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+// HTMLAudioElement 音频
|
|
|
|
+const audioData = reactive({
|
|
|
|
+ tick: null as unknown as HTMLAudioElement,
|
|
|
|
+ tock: null as unknown as HTMLAudioElement,
|
|
|
|
+});
|
|
|
|
+
|
|
|
|
+const createAudio = (src: string): Promise<HTMLAudioElement | null> => {
|
|
|
|
+ return new Promise((resolve) => {
|
|
|
|
+ const a = new Audio(src + '?v=' + Date.now());
|
|
|
|
+ a.load();
|
|
|
|
+ a.onloadedmetadata = () => {
|
|
|
|
+ resolve(a);
|
|
|
|
+ };
|
|
|
|
+ a.onerror = () => {
|
|
|
|
+ resolve(null);
|
|
|
|
+ };
|
|
|
|
+ });
|
|
|
|
+};
|
|
|
|
+
|
|
/** 设置节拍器
|
|
/** 设置节拍器
|
|
* @param beatLengthInMilliseconds 节拍间隔时间
|
|
* @param beatLengthInMilliseconds 节拍间隔时间
|
|
* @param beat 节拍数
|
|
* @param beat 节拍数
|
|
@@ -54,9 +73,9 @@ export const handleStartTick = async () => {
|
|
// 如果是ios手机,需要强制使用audio,不然部分系统版本第一次播放没有声音
|
|
// 如果是ios手机,需要强制使用audio,不然部分系统版本第一次播放没有声音
|
|
html5: browserInfo.ios,
|
|
html5: browserInfo.ios,
|
|
});
|
|
});
|
|
|
|
+
|
|
tickData.source2 = new Howl({
|
|
tickData.source2 = new Howl({
|
|
src: tockAndTick.tock,
|
|
src: tockAndTick.tock,
|
|
- html5: browserInfo.ios,
|
|
|
|
});
|
|
});
|
|
tickData.state = "ok";
|
|
tickData.state = "ok";
|
|
}
|
|
}
|
|
@@ -66,6 +85,7 @@ export const handleStartTick = async () => {
|
|
// 提前结束, 直接放回false
|
|
// 提前结束, 直接放回false
|
|
if (tickData.tickEnd) return false;
|
|
if (tickData.tickEnd) return false;
|
|
const source = i === 0 ? tickData.source1 : i === tickData.len ? null : tickData.source2;
|
|
const source = i === 0 ? tickData.source1 : i === tickData.len ? null : tickData.source2;
|
|
|
|
+ // const source = i === 0 ? audioData.tick : i === tickData.len ? null : audioData.tock;
|
|
await handlePlay(i, source)
|
|
await handlePlay(i, source)
|
|
}
|
|
}
|
|
tickData.show = false;
|
|
tickData.show = false;
|
|
@@ -79,6 +99,18 @@ export default defineComponent({
|
|
const handleClose = () => {
|
|
const handleClose = () => {
|
|
tickData.tickEnd = true
|
|
tickData.tickEnd = true
|
|
};
|
|
};
|
|
|
|
+ onMounted(() => {
|
|
|
|
+ Promise.all([createAudio(tockAndTick.tick), createAudio(tockAndTick.tock)]).then(
|
|
|
|
+ ([tick, tock]) => {
|
|
|
|
+ if (tick) {
|
|
|
|
+ audioData.tick = tick;
|
|
|
|
+ }
|
|
|
|
+ if (tock) {
|
|
|
|
+ audioData.tock = tock;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+ });
|
|
return () => (
|
|
return () => (
|
|
<Popup class={styles.popup} v-model:show={tickData.show} closeable onClickCloseIcon={handleClose}>
|
|
<Popup class={styles.popup} v-model:show={tickData.show} closeable onClickCloseIcon={handleClose}>
|
|
<div class={styles.dots}>
|
|
<div class={styles.dots}>
|