|
@@ -1,5 +1,5 @@
|
|
|
import { computed, defineComponent, nextTick, onMounted, onUnmounted, reactive, ref } from "vue";
|
|
|
-import ABCJS, { AbcElem, AbcVisualParams, ClickListenerAnalysis, ClickListenerDrag, SynthObjectController } from "abcjs";
|
|
|
+import ABCJS, { AbcElem, AbcVisualParams, ClickListenerAnalysis, ClickListenerDrag, NoteTimingEvent, SynthObjectController } from "abcjs";
|
|
|
import "ABCJS/ABCJS-audio.css";
|
|
|
import styles from "./index.module.less";
|
|
|
import { showConfirmDialog, showToast } from "vant";
|
|
@@ -25,6 +25,7 @@ import { Close } from "@vicons/ionicons5";
|
|
|
import { UseDraggable } from "@vueuse/components";
|
|
|
import { getQuery } from "/src/utils/queryString";
|
|
|
import Metronome, { metronomeData } from "/src/helpers/metronome";
|
|
|
+import cleanDeep from "clean-deep";
|
|
|
|
|
|
const allPitches = [
|
|
|
"C,,,,",
|
|
@@ -107,6 +108,7 @@ export const initMusic = (total: number): IMeasure[] => {
|
|
|
celf: "",
|
|
|
key: "",
|
|
|
repeat: "",
|
|
|
+ meter: "",
|
|
|
notes: [
|
|
|
{
|
|
|
accidental: "",
|
|
@@ -491,18 +493,52 @@ export default defineComponent({
|
|
|
renderSvg();
|
|
|
resetMidi(data.drawCount > 0 ? true : false);
|
|
|
renderBoxRect();
|
|
|
+ // productMetronomeData();
|
|
|
resolve(1);
|
|
|
+
|
|
|
textAreaRef.value && (textAreaRef.value.value = data.music);
|
|
|
data.drawCount++;
|
|
|
-
|
|
|
- const times = new ABCJS.TimingCallbacks(abcData.visualObj);
|
|
|
- console.log("🚀 ~ times:", times)
|
|
|
- metronomeData.metro = new Metronome();
|
|
|
- metronomeData.metro.init(times.noteTimings)
|
|
|
});
|
|
|
});
|
|
|
};
|
|
|
|
|
|
+ /** 生成曲谱节拍器数据 */
|
|
|
+ const productMetronomeData = () => {
|
|
|
+ const times = new ABCJS.TimingCallbacks(abcData.visualObj);
|
|
|
+ const list: any[] = [];
|
|
|
+ // length - 1是为了去除最后一个空的结束事件
|
|
|
+ for(let i = 0; i < times.noteTimings.length - 1; i++){
|
|
|
+ const timeNote = times.noteTimings[i];
|
|
|
+ const abcNote = getNextNote(timeNote.startChar as number)
|
|
|
+ let indexStr: any = abcNote.chord?.find((n) => n.position === "left")?.name || "";
|
|
|
+ indexStr = indexStr.split(".").map((n: string) => Number(n));
|
|
|
+ if (indexStr.length === 2) {
|
|
|
+ const measure = abcData.abc.measures[indexStr[0]];
|
|
|
+ const meter = measure.meter ?? abcData.abc.meter;
|
|
|
+ const reg = new RegExp(/M:(\d+)\/\d+/);
|
|
|
+ const numerator = Number(meter.match(reg)?.[1]);
|
|
|
+ // console.log("🚀 ~ reg:", meter.match(reg)?.[1], abcData.abc.meter)
|
|
|
+ // console.log("🚀 ~ measure:", measure)
|
|
|
+ const note = measure.notes[indexStr[1]];
|
|
|
+ list.push({
|
|
|
+ ...note,
|
|
|
+ timeNote,
|
|
|
+ abcNote,
|
|
|
+ measure:{
|
|
|
+ numerator
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ console.log('abcData.abc.measures', list)
|
|
|
+ metronomeData.metro = new Metronome();
|
|
|
+ try {
|
|
|
+ metronomeData.metro.init(list)
|
|
|
+ } catch (error) {
|
|
|
+ console.log("🚀 ~ 生成节拍器数据错误:", error)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
// 高亮选中的音符
|
|
|
const rangeHighlight = (startChar: number) => {
|
|
|
// console.log(data.active.endChar, abcData.visualObj.getElementFromChar(data.active.startChar));
|
|
@@ -727,10 +763,10 @@ export default defineComponent({
|
|
|
if (type === "meter") {
|
|
|
if (data.active) {
|
|
|
if (!activeNote) return;
|
|
|
- const note = abcData.abc.measures[data.active.measureIndex].notes[0];
|
|
|
- note.meter = `[${value}]`;
|
|
|
+ const measure = abcData.abc.measures[data.active.measureIndex];
|
|
|
+ measure.meter = `[${value}]`;
|
|
|
await handleResetRender();
|
|
|
- const oldNote = useIndexGetNote(`${data.active.measureIndex}.0`);
|
|
|
+ const oldNote = useIndexGetNote(`${data.active.measureIndex}.${data.active.noteIndex}`);
|
|
|
rangeHighlight(oldNote.startChar);
|
|
|
} else {
|
|
|
abcData.abc.meter = value;
|
|
@@ -1118,7 +1154,7 @@ export default defineComponent({
|
|
|
name: data.musicName,
|
|
|
creator: data.creator,
|
|
|
creationConfig: renderMeasures(abcData.abc, { hiddenIndex: true }),
|
|
|
- creationData: JSON.stringify(abcData.abc),
|
|
|
+ creationData: JSON.stringify(cleanDeep(abcData.abc)),
|
|
|
id: data.musicId,
|
|
|
subjectId: 3,
|
|
|
});
|