Parcourir la source

点击修改音符后,选择下一个音符可以继续修改,小节时值满了,跳转到下一个小节

liushengqiang il y a 1 an
Parent
commit
472d8a6acd
2 fichiers modifiés avec 100 ajouts et 78 suppressions
  1. 91 73
      src/pc/home/index.tsx
  2. 9 5
      src/pc/home/runtime.ts

+ 91 - 73
src/pc/home/index.tsx

@@ -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;
 			}
 		};

+ 9 - 5
src/pc/home/runtime.ts

@@ -214,11 +214,15 @@ export const renderMeasures = (abc: IAbc) => {
 			text += note.accidental; // 临时升降记号
 			text += note.content; // 音符
 			// 音符时值
-			if(note.dot){
-				text += note.dot; // 附点
-			} else {
-				text += note.noteType; // 音符类型
-			}
+			text += note.noteType;
+			text += note.dot;
+			
+			// if(note.dot){
+			// 	text += note.dot; // 附点
+			// } else {
+			// 	text += note.noteType; // 音符类型
+			// }
+
 			text += note.tieline; // 延音
 			if (note.tie.includes(")")) {
 				// 连音线 后