Ver Fonte

feat: 摇篮曲多轨合并展示,播放光标问题特殊处理

TIANYONG há 1 ano atrás
pai
commit
072e91ee6d
2 ficheiros alterados com 117 adições e 29 exclusões
  1. 18 0
      src/helpers/customMusicScore.ts
  2. 99 29
      src/state.ts

+ 18 - 0
src/helpers/customMusicScore.ts

@@ -156,6 +156,18 @@ export const resetGivenFormate = () => {
 	
 };
 
+const initNoteCoord = () => {
+	const allNoteDot: any = Array.from(document.querySelectorAll('.node-dot'));
+ 	state.noteCoords = allNoteDot.map((note: any) => {
+		const note_bbox = note?.getBoundingClientRect?.() || { x: 0, y: 0 };
+		return {
+			x: note_bbox.x,
+			y: note_bbox.y
+		}
+	})
+	console.log(11111,state.noteCoords)
+}
+
 export const moveGracePosition = (needTrans?: boolean) => {
 	/**
 	 * TODO:曲目:摇篮曲(节奏练习)-倚音位置 特殊处理
@@ -177,6 +189,7 @@ export const moveGracePosition = (needTrans?: boolean) => {
 			// }
 		} else {
 			const signatureDom = document.getElementById('auto2784'), fixedSigntureDom = document.getElementById('auto3022');
+			const signatureDom2 = document.getElementById('auto2744'),fixedSigntureDom2 = document.getElementById('auto2978');
 			const needTransLateDom: any = document.getElementById('vf-auto2178')?.getElementsByClassName('vf-modifier')?.[0], fixednNeedTransLateDom: any = document.getElementById('vf-auto2390')?.getElementsByClassName('vf-modifier')?.[0];
 			const arrowDom = document.getElementById('vf-auto2178-lines'), fixedArrowDom = document.getElementById('vf-auto2390-lines');
 			
@@ -190,6 +203,8 @@ export const moveGracePosition = (needTrans?: boolean) => {
 
 			if (signatureDom) signatureDom.style.display = 'none';
 			if (fixedSigntureDom) fixedSigntureDom.style.display = 'none';
+			if (signatureDom2) signatureDom2.style.display = 'none';
+			if (fixedSigntureDom2) fixedSigntureDom2.style.display = 'none';
 			if (needTransLateDom) needTransLateDom.style.transform = 'translateX(-0.65rem)';
 			if (fixednNeedTransLateDom) fixednNeedTransLateDom.style.transform = 'translateX(-0.65rem)';
 			if (arrowDom) {
@@ -224,6 +239,9 @@ export const resetFormate = () => {
 	// if (state.extStyleConfigJson || !container.value) return;
 	if (!container.value) return;
 	moveGracePosition();
+	// setTimeout(() => {
+	// 	initNoteCoord();
+	// }, 0);
 	const stafflines: SVGAElement[] = Array.from((container.value as HTMLElement).querySelectorAll(".staffline"));
 	const baseStep = 4; // 两个元素相间,的间距
 	const musicalDistance = 28; // 音阶与第一条线谱的间距,默认设置为28

+ 99 - 29
src/state.ts

@@ -469,6 +469,8 @@ const state = reactive({
   isAttendClass: false,
   /** 引导页信息 */
   guideInfo: null as any,
+  noteCoords: [] as any,
+  specialPosInit: false,
 });
 const browserInfo = browser();
 let offset_duration = 0;
@@ -729,7 +731,48 @@ export const gotoCustomNote = (index: number) => {
     state.osmd.cursor.next();
   }
 };
-const setCursorPosition = (note: any, cursor: any) => {
+
+// 找出离目标元素最近的音符
+const computedDistance = (x: number, y: number) => {
+  let minDistance = -1, minidx = 0;
+  let a, b, c;
+  state.noteCoords.forEach((note: any, idx: any) => {
+    //a,b为直角三角形的两个直角边
+    a = Math.abs(note.x - x)
+    b = Math.abs(note.y - y)
+    //c为直角三角形的斜边
+    c = Math.sqrt(a * a + b * b) as 0
+    c = Number(c.toFixed(0)) as 0
+    if (c !== 0 && (minDistance === - 1 || c < minDistance)) {
+      //min为元素中离目标元素最近元素的距离
+      minDistance = c
+      minidx = idx
+    }		
+  })
+  return minidx
+};
+
+const customNotePosition = (note: any, cursor: any) => {
+  const specialIds = ['1788850864767643649','1788502467554750466','1788501975122489346'];
+  if (specialIds.includes(state.cbsExamSongId) && note.multipleRestMeasures === 0) {
+    const pageLeft = document.getElementById('scrollContainer')?.getBoundingClientRect()?.x || 0;
+    // 元素的位置
+    const element = document.getElementById('cursorImg-0')?.getBoundingClientRect?.() || { x: 0, y: 0 };
+    // 找出距离元素最近的音符
+    if (element.x && element.y) {
+      const noteIdx = computedDistance(element.x, element.y);
+      const targetX = state.noteCoords[noteIdx]?.x - pageLeft;
+      console.log('音符索引',noteIdx)
+      cursor.cursorElement.style.left = targetX + "px";
+      cursor.cursorElement.style.transform = `translateX(0px)`;
+    }
+    
+  }
+}
+
+const setCursorPosition = (note: any, cursor: any, flag?: string) => {
+  // console.log('音符',note?.i,state.osmd.Cursor.noteGraphicalId,note.svgElement?.attrs?.id)
+  
   if (state.musicRenderType === EnumMusicRenderType.firstTone || state.musicRenderType === EnumMusicRenderType.fixedTone) {
     /**
      * bug:#9920、#9940
@@ -737,35 +780,54 @@ const setCursorPosition = (note: any, cursor: any) => {
      */
     if (state.sectionStatus && state.playState === 'paused' && state.sectionFirst && (note.multipleRestMeasures || note.MeasureNumberXML !== state.sectionFirst?.MeasureNumberXML)) {
       return
+
     }
-    nextTick(() => {
-      let bbox = note.bbox;
-      if (!bbox) {
-        const musicContainer = document.getElementById("musicAndSelection")?.getBoundingClientRect() || {
-          x: 0,
-          y: 0,
-        };
-        const parentLeft = musicContainer.x || 0;
-        const noteEle = document.querySelector(`#vf-${note.svgElement?.attrs?.id}`);
-        if (noteEle) {
-          const noteHead = noteEle.querySelector(".vf-numbered-note-head");
-          const noteHeadBbox = noteHead?.getBoundingClientRect?.();
-          if (noteHeadBbox) {
-            note.bbox = {
-              left: noteHeadBbox.x - parentLeft - noteHeadBbox.width / 4,
-              width: noteHeadBbox.width * 1.5,
-            };
-            bbox = note.bbox;
+    const specialIds = ['1788850864767643649','1788502467554750466','1788501975122489346'];
+    if (specialIds.includes(state.cbsExamSongId) && note.multipleRestMeasures === 0) {
+        //console.log('音符idx',note?.i,cursor.cursorElement.style.left)
+        const cursorLeft = cursor?.cursorElement?.style?.left ? parseFloat(cursor.cursorElement.style.left) : 0;
+        let patchX = 0;
+        if (state.cbsExamSongId == '1788502467554750466') {
+          patchX = note.i == 0 ? 31 : (note.i == 8 || note.i == 14 || note.i == 30 || note.i == 45 || note.i == 51 || note.i == 59 || note.i == 65) ? -10 : note.i == 67 ? 31 : 0;
+        } else if (state.cbsExamSongId == '1788501975122489346') {
+          patchX = note.i == 0 ? 21 : (note.i == 8 || note.i == 59 || note.i == 65) ? -6 : (note.i == 9 || note.i == 10 || note.i == 12 || note.i == 13) ? 3 : (note.i == 14 || note.i == 30 || note.i == 45 || note.i == 51) ? -8 : (note.i >= 15 || note.i <= 29) || (note.i >= 31 || note.i <= 36) || (note.i >= 38 || note.i <= 44) || (note.i >= 46 || note.i <= 50) || (note.i >= 52 || note.i <= 58) || (note.i >= 60 || note.i <= 64) || (note.i == 66) ? 4 : 0;
+        }
+        if (flag === 'refresh' || (flag === 'init' && !state.specialPosInit)) {
+          cursor.cursorElement.style.left = cursorLeft + patchX + "px";
+          state.specialPosInit = true;
+        }
+    } else {
+      nextTick(() => {
+        let bbox = note.bbox;
+        if (!bbox) {
+          const musicContainer = document.getElementById("musicAndSelection")?.getBoundingClientRect() || {
+            x: 0,
+            y: 0,
+          };
+          const parentLeft = musicContainer.x || 0;
+          const noteEle = document.querySelector(`#vf-${note.svgElement?.attrs?.id}`);
+          if (noteEle) {
+            const noteHead = noteEle.querySelector(".vf-numbered-note-head");
+            const noteHeadBbox = noteHead?.getBoundingClientRect?.();
+            if (noteHeadBbox) {
+              note.bbox = {
+                left: noteHeadBbox.x - parentLeft - noteHeadBbox.width / 4,
+                width: noteHeadBbox.width * 1.5,
+              };
+              bbox = note.bbox;
+            }
           }
         }
-      }
-      if (!bbox) return;
-      const baseW = state.platform === IPlatform.PC ? 29 : 18;
-      const width = (bbox.width - baseW) / 3;
-      // console.log(555555,bbox.left,width)
-      cursor.cursorElement.style.left = bbox.left + "px";
-      cursor.cursorElement.style.transform = `translateX(${width}px)`;
-    });
+        if (!bbox) return;
+        const baseW = state.platform === IPlatform.PC ? 29 : 18;
+        const width = (bbox.width - baseW) / 3;
+        // console.log(555555,bbox.left,width)
+        cursor.cursorElement.style.left = bbox.left + "px";
+        cursor.cursorElement.style.transform = `translateX(${width}px)`;
+      });
+    }
+
+
   }
 };
 /** 
@@ -778,7 +840,7 @@ export const gotoNext = (note: any, skipNote?: boolean) => {
 
   if (state.activeNoteIndex === note.i) {
     try {
-      setCursorPosition(note, state.osmd.cursor);
+      setCursorPosition(note, state.osmd.cursor, 'init');
     } catch (error) {
       console.log(error);
     }
@@ -790,17 +852,25 @@ export const gotoNext = (note: any, skipNote?: boolean) => {
   state.activeMeasureIndex = note.MeasureNumberXML;
 
   if (prev && num - prev === 1) {
+    // console.log('跳转音符',11111,osmd.cursor)
+    // if (!note.id && note.multipleRestMeasures === 0) {
+
+    // } else {
+    //   osmd.cursor.next();
+    // }
     osmd.cursor.next();
+    
   } else if (prev && num - prev > 0) {
     while (num - prev > 0) {
       prev++;
+      // console.log('跳转音符',22222)
       osmd.cursor.next();
     }
   } else {
     gotoCustomNote(num);
   }
   try {
-    setCursorPosition(note, state.osmd.cursor);
+    setCursorPosition(note, state.osmd.cursor, 'refresh');
   } catch (error) {
     console.log(error);
   }