|
@@ -0,0 +1,106 @@
|
|
|
+import { reactive } from 'vue';
|
|
|
+import tockAndTick from './tockAndTick.json';
|
|
|
+import { Howl } from 'howler';
|
|
|
+import { setting } from './setting';
|
|
|
+
|
|
|
+const tickData = reactive({
|
|
|
+ list: [] as number[],
|
|
|
+ len: 0,
|
|
|
+ tickEnd: false,
|
|
|
+ /** 节拍器时间 */
|
|
|
+ beatLengthInMilliseconds: 0,
|
|
|
+ state: '',
|
|
|
+ source1: '' as any,
|
|
|
+ source2: '' as any,
|
|
|
+ index: 0,
|
|
|
+ show: false
|
|
|
+});
|
|
|
+
|
|
|
+let diffTime = 0; // 每一次节拍时间差
|
|
|
+const handlePlay = (i: number, source: any) => {
|
|
|
+ return new Promise(resolve => {
|
|
|
+ const startTime = +new Date();
|
|
|
+ setTimeout(() => {
|
|
|
+ diffTime = 0;
|
|
|
+ if (tickData.tickEnd) {
|
|
|
+ resolve(i);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ tickData.index++;
|
|
|
+
|
|
|
+ if (source) source.play();
|
|
|
+ resolve(i);
|
|
|
+ const endTime = +new Date();
|
|
|
+ // diffTime = endTime - startTime - tickData.beatLengthInMilliseconds;
|
|
|
+ // console.log(endTime - startTime, diffTime);
|
|
|
+ }, tickData.beatLengthInMilliseconds - diffTime);
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+// let timeSppedEnum = 16.7;
|
|
|
+// let payBeatTime = new Date().getTime();
|
|
|
+// const proofTime = () => {
|
|
|
+// if (setting.playState !== 'play') {
|
|
|
+// return;
|
|
|
+// }
|
|
|
+// let startTime = Date.now();
|
|
|
+// requestAnimationFrame(() => {
|
|
|
+// const endTime = Date.now();
|
|
|
+// // 渲染时间大于16.6,就会让页面卡顿, 如果渲染时间大与16.6就下一个渲染帧去计算
|
|
|
+// if (endTime - startTime < 16.7) {
|
|
|
+// handlePlaying();
|
|
|
+// proofTime();
|
|
|
+// } else {
|
|
|
+// setTimeout(() => {
|
|
|
+// handlePlaying();
|
|
|
+// proofTime();
|
|
|
+// }, 16.7);
|
|
|
+// }
|
|
|
+// });
|
|
|
+// };
|
|
|
+
|
|
|
+/** 设置节拍器
|
|
|
+ * @param beatLengthInMilliseconds 节拍间隔时间
|
|
|
+ * @param beat 节拍数
|
|
|
+ */
|
|
|
+export const handleInitTick = (
|
|
|
+ beatLengthInMilliseconds: number,
|
|
|
+ beat: number
|
|
|
+) => {
|
|
|
+ tickData.state = '';
|
|
|
+ tickData.beatLengthInMilliseconds = beatLengthInMilliseconds;
|
|
|
+ tickData.len = beat;
|
|
|
+};
|
|
|
+
|
|
|
+/** 开始节拍器 */
|
|
|
+export const handleStartTick = async () => {
|
|
|
+ tickData.show = true;
|
|
|
+ tickData.tickEnd = false;
|
|
|
+ if (tickData.state !== 'ok') {
|
|
|
+ tickData.source1 = new Howl({
|
|
|
+ src: tockAndTick.tick
|
|
|
+ });
|
|
|
+ tickData.source2 = new Howl({
|
|
|
+ src: tockAndTick.tock
|
|
|
+ });
|
|
|
+ tickData.state = 'ok';
|
|
|
+ }
|
|
|
+ tickData.index = 0;
|
|
|
+ tickData.beatLengthInMilliseconds = (60 / setting.speed) * 1000;
|
|
|
+ for (let i = 0; i <= tickData.len; i++) {
|
|
|
+ // 提前结束, 直接放回false
|
|
|
+ if (tickData.tickEnd) return false;
|
|
|
+ const source =
|
|
|
+ i === 0 ? tickData.source1 : i === tickData.len ? null : tickData.source2;
|
|
|
+
|
|
|
+ await handlePlay(i, source);
|
|
|
+ }
|
|
|
+ console.log(+new Date());
|
|
|
+ tickData.show = false;
|
|
|
+ return true;
|
|
|
+};
|
|
|
+
|
|
|
+/** 节拍器暂停 */
|
|
|
+export const hendleEndTick = () => {
|
|
|
+ tickData.tickEnd = true;
|
|
|
+};
|