|
@@ -283,7 +283,7 @@ export default defineComponent({
|
|
|
// abcData.visualObj.engraver.rangeHighlight(abcElem.startChar, abcElem.endChar);
|
|
|
// }
|
|
|
if (drag && drag.step) {
|
|
|
- handleMoveNote("drag", drag.step);
|
|
|
+ handleChange({ type: "move", value: { action: "drag", step: drag.step } });
|
|
|
return;
|
|
|
}
|
|
|
if (!abcElem?.midiPitches) return;
|
|
@@ -468,7 +468,9 @@ export default defineComponent({
|
|
|
...abcData.abcOptions,
|
|
|
visualTranspose: abcData.abc.visualTranspose,
|
|
|
})[0];
|
|
|
- console.log("🚀 ~ visualObj:", abcData.visualObj);
|
|
|
+ if (data.drawCount <3 ){
|
|
|
+ console.log("🚀 ~ visualObj:", abcData.visualObj);
|
|
|
+ }
|
|
|
};
|
|
|
|
|
|
const renderBoxRect = () => {
|
|
@@ -558,11 +560,15 @@ export default defineComponent({
|
|
|
* @returns
|
|
|
*/
|
|
|
const handleChange = async (params: { type: string; value: any }) => {
|
|
|
+ abcData.synthControl.disable(true);
|
|
|
+ if (data.playState) {
|
|
|
+ data.playState = false;
|
|
|
+ }
|
|
|
const type = params.type;
|
|
|
const value = params.value;
|
|
|
const activeNote =
|
|
|
abcData.abc.measures[data.active?.measureIndex]?.notes[data.active?.noteIndex] || null;
|
|
|
- console.log(params, activeNote);
|
|
|
+ // console.log(params, activeNote);
|
|
|
if (type === "type") {
|
|
|
// 设置音符类型
|
|
|
data.noteType = value;
|
|
@@ -607,59 +613,78 @@ export default defineComponent({
|
|
|
if (_values[1]) {
|
|
|
activeNote.accidental = _values[1] || "";
|
|
|
}
|
|
|
+ data.active.isFirstChecked = false;
|
|
|
+ }
|
|
|
+ await handleResetRender();
|
|
|
+ const oldNote = useIndexGetNote(`${data.active.measureIndex}.${data.active.noteIndex}`);
|
|
|
+ if (oldNote?.abselem?.beam?.elems?.length) {
|
|
|
+ // 判断是否需要分割beam
|
|
|
+ const elems: AbcElem[] = oldNote.abselem.beam.elems;
|
|
|
+ const beatDuration = abcData.visualObj.getBeatLength();
|
|
|
+ const beamLength = elems.map((n) => n.duration).reduce((a, b) => a + b);
|
|
|
+ if (beamLength >= beatDuration) {
|
|
|
+ abcData.abc.measures[data.active.measureIndex].notes[data.active.noteIndex].segno = " ";
|
|
|
+ await handleResetRender();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (oldNote?.midiPitches) {
|
|
|
+ ABCJS.synth.playEvent(oldNote.midiPitches, oldNote.midiGraceNotePitches, 1000);
|
|
|
+ }
|
|
|
+ const nextNote =
|
|
|
+ abcData.abc.measures[data.active.measureIndex]?.notes[data.active.noteIndex + 1];
|
|
|
+ if (nextNote) {
|
|
|
+ const abcNextElem: AbcElem = useIndexGetNote(
|
|
|
+ `${data.active.measureIndex}.${data.active.noteIndex + 1}`
|
|
|
+ );
|
|
|
+ rangeHighlight(abcNextElem.startChar);
|
|
|
+ data.active = {
|
|
|
+ ...abcNextElem,
|
|
|
+ measureIndex: data.active.measureIndex,
|
|
|
+ noteIndex: data.active.noteIndex + 1,
|
|
|
+ isFirstChecked: true,
|
|
|
+ };
|
|
|
} else {
|
|
|
const notes = getMeasureNotes(data.active.measureIndex);
|
|
|
const duration = notes.map((n) => n.duration).reduce((a, b) => a + b);
|
|
|
if (duration >= 1) {
|
|
|
- message.warning("小节内音符总时值过长");
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- handleCreateNote(
|
|
|
- data.active.measureIndex,
|
|
|
- data.active.noteIndex,
|
|
|
- createNote({
|
|
|
- content: _values[0],
|
|
|
- noteType: data.noteType,
|
|
|
- accidental: _values[1] || "",
|
|
|
- })
|
|
|
- );
|
|
|
- }
|
|
|
- await handleResetRender();
|
|
|
- let _abcElem: AbcElem;
|
|
|
- if (data.active.isFirstChecked) {
|
|
|
- data.active.isFirstChecked = false;
|
|
|
- _abcElem = rangeHighlight(data.active.startChar);
|
|
|
- } else {
|
|
|
- const oldElem: AbcElem = abcData.visualObj.getElementFromChar(data.active.startChar);
|
|
|
- const abcElem: AbcElem = abcData.visualObj.getElementFromChar(oldElem.endChar);
|
|
|
- if (abcElem) {
|
|
|
- let indexStr: any = abcElem.chord?.find((n) => n.position === "left")?.name || "";
|
|
|
- indexStr = indexStr.split(".").map((n: string) => Number(n));
|
|
|
+ // 小节内音符总时值过长,自动跳转到下一小节
|
|
|
+ const nextMeasureNote = abcData.abc.measures[data.active.measureIndex + 1]?.notes[0];
|
|
|
+ if (nextMeasureNote) {
|
|
|
+ const abcNextElem: AbcElem = useIndexGetNote(`${data.active.measureIndex + 1}.${0}`);
|
|
|
+ rangeHighlight(abcNextElem.startChar);
|
|
|
+ data.active = {
|
|
|
+ ...abcNextElem,
|
|
|
+ measureIndex: data.active.measureIndex + 1,
|
|
|
+ noteIndex: 0,
|
|
|
+ isFirstChecked: true,
|
|
|
+ };
|
|
|
+ } else {
|
|
|
+ // 到最后一个小节的最后一个音符了
|
|
|
+ rangeHighlight(data.active.startChar);
|
|
|
+ data.active.isFirstChecked = true;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ handleCreateNote(
|
|
|
+ data.active.measureIndex,
|
|
|
+ data.active.noteIndex,
|
|
|
+ createNote({
|
|
|
+ content: "z",
|
|
|
+ noteType: data.noteType,
|
|
|
+ })
|
|
|
+ );
|
|
|
+ await handleResetRender();
|
|
|
+ const newNote = useIndexGetNote(
|
|
|
+ `${data.active.measureIndex}.${data.active.noteIndex + 1}`
|
|
|
+ );
|
|
|
+ rangeHighlight(newNote.startChar);
|
|
|
data.active = {
|
|
|
- ...abcElem,
|
|
|
- measureIndex: indexStr[0],
|
|
|
- noteIndex: indexStr[1],
|
|
|
- isFirstChecked: false,
|
|
|
+ ...newNote,
|
|
|
+ measureIndex: data.active.measureIndex,
|
|
|
+ noteIndex: data.active.noteIndex + 1,
|
|
|
+ isFirstChecked: true,
|
|
|
};
|
|
|
- const beam = (abcElem.abselem as any).beam;
|
|
|
- if (beam) {
|
|
|
- const elems: AbcElem[] = beam.elems;
|
|
|
- if (elems.length) {
|
|
|
- const beatDuration = abcData.visualObj.getBeatLength();
|
|
|
- const beamLength = elems.map((n) => n.duration).reduce((a, b) => a + b);
|
|
|
- if (beamLength >= beatDuration) {
|
|
|
- abcData.abc.measures[data.active.measureIndex].notes[data.active.noteIndex].segno =
|
|
|
- " ";
|
|
|
- await handleResetRender();
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
}
|
|
|
- _abcElem = rangeHighlight(abcElem.startChar);
|
|
|
}
|
|
|
- if (!_abcElem?.midiPitches) return;
|
|
|
- ABCJS.synth.playEvent(_abcElem.midiPitches, _abcElem.midiGraceNotePitches, 1000);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -717,6 +742,8 @@ export default defineComponent({
|
|
|
if (!activeNote) return;
|
|
|
activeNote.meter = `[${value}]`;
|
|
|
await handleResetRender();
|
|
|
+ const oldNote = useIndexGetNote(`${data.active.measureIndex}.${data.active.noteIndex}`);
|
|
|
+ rangeHighlight(oldNote.startChar);
|
|
|
} else {
|
|
|
abcData.abc.meter = value;
|
|
|
await handleResetRender();
|
|
@@ -882,11 +909,9 @@ export default defineComponent({
|
|
|
showToast("请先选择音符");
|
|
|
return;
|
|
|
}
|
|
|
- const activeNote =
|
|
|
- abcData.abc.measures[data.active.measureIndex]?.notes[data.active.noteIndex] || null;
|
|
|
if (!activeNote) return;
|
|
|
- activeNote.dot = activeNote.dot ? "" : NOTE_DOT[activeNote.noteType];
|
|
|
- console.log("🚀 ~ activeNote:", activeNote)
|
|
|
+ activeNote.dot = activeNote.dot ? "" : value;
|
|
|
+ // activeNote.dot = activeNote.dot ? "" : NOTE_DOT[activeNote.noteType];
|
|
|
await handleResetRender();
|
|
|
rangeHighlight(data.active.startChar);
|
|
|
}
|
|
@@ -900,6 +925,19 @@ export default defineComponent({
|
|
|
await handleResetRender();
|
|
|
rangeHighlight(data.active.startChar);
|
|
|
}
|
|
|
+
|
|
|
+ // 移动音符
|
|
|
+ if (type === "move") {
|
|
|
+ const step = value._step ? value._step : value.action === "up" ? -1 : 1;
|
|
|
+ if (!activeNote) return;
|
|
|
+ activeNote.content = moveNote(activeNote.content, step);
|
|
|
+ // arr now contains elements that are either a chord, a decoration, a note name, or anything else. It can be put back to its original string with .join("").
|
|
|
+
|
|
|
+ await handleResetRender();
|
|
|
+ const _abcElem = rangeHighlight(data.active.startChar);
|
|
|
+ if (!_abcElem?.midiPitches) return;
|
|
|
+ ABCJS.synth.playEvent(_abcElem.midiPitches, _abcElem.midiGraceNotePitches, 1000);
|
|
|
+ }
|
|
|
};
|
|
|
|
|
|
const getNextNote = (index: number): AbcElem => {
|
|
@@ -1020,26 +1058,6 @@ export default defineComponent({
|
|
|
await handleResetRender();
|
|
|
};
|
|
|
|
|
|
- /**
|
|
|
- * 移动音符
|
|
|
- * @param note 音符
|
|
|
- * @param step 移动步数
|
|
|
- */
|
|
|
- const handleMoveNote = async (type: "up" | "donw" | "drag", _step?: number) => {
|
|
|
- if (!data.active) return;
|
|
|
- const step = _step ? _step : type === "up" ? -1 : 1;
|
|
|
- const activeNote =
|
|
|
- abcData.abc.measures[data.active.measureIndex]?.notes[data.active.noteIndex] || null;
|
|
|
- if (!activeNote) return;
|
|
|
- activeNote.content = moveNote(activeNote.content, step);
|
|
|
- // arr now contains elements that are either a chord, a decoration, a note name, or anything else. It can be put back to its original string with .join("").
|
|
|
-
|
|
|
- await handleResetRender();
|
|
|
- const _abcElem = rangeHighlight(data.active.startChar);
|
|
|
- if (!_abcElem?.midiPitches) return;
|
|
|
- ABCJS.synth.playEvent(_abcElem.midiPitches, _abcElem.midiGraceNotePitches, 1000);
|
|
|
- };
|
|
|
-
|
|
|
const handleKeyUp = (e: KeyboardEvent) => {
|
|
|
if (!data.active) return false;
|
|
|
console.log(e.key);
|
|
@@ -1050,7 +1068,7 @@ export default defineComponent({
|
|
|
if (["ArrowUp", "ArrowDown"].includes(e.key)) {
|
|
|
e.preventDefault();
|
|
|
e.stopPropagation();
|
|
|
- handleMoveNote(e.key === "ArrowUp" ? "up" : "donw");
|
|
|
+ handleChange({ type: "move", value: { action: e.key === "ArrowUp" ? "up" : "donw" } });
|
|
|
return false;
|
|
|
}
|
|
|
};
|