ソースを参照

Merge branch 'feature-tianyong-newVersion' into ktyq-test-new

TIANYONG 6 ヶ月 前
コミット
c5370c31e1

+ 7 - 0
src/helpers/formateMusic.ts

@@ -1238,7 +1238,11 @@ export const formateTimes = (osmd: OpenSheetMusicDisplay) => {
 			// console.log('频率',note?.pitch?.frequency,i)
 			/**
 			 * evxml的曲子,如果曲谱xml中带有times信息,则音符时值优先取times中的值
+			 * 曲子:1795013295024062466(春暖花开),如果音符有times信息,休止符没有times信息,此种规则是认为休止符不参与时值计算的,需要过滤掉该休止符
 			 */
+			if (state.isEvxml && note.isRestFlag && note?.noteTimeInfo?.length === 0 && state.xmlHasTimes) {
+				continue;
+			}
 			let evNoteStartTime = 0, evNoteEndTime = 0;
 			if (state.isEvxml && note?.noteTimeInfo?.length) {
 				const idx = noteIds.filter((item: any) => item === svgElement?.attrs.id)?.length || 0
@@ -1552,6 +1556,9 @@ const analyzeEvxml = (xmlParse: any, xmlUrl?: string) => {
 	const firstMeasure = xmlParse.getElementsByTagName("measure")[0];
 	if (firstMeasure) {
 		const firstNoteBeginTime = firstMeasure.getElementsByTagName("times")[0]?.getElementsByTagName("time")[0]?.getAttribute('begin');
+		if (firstNoteBeginTime) {
+			state.xmlHasTimes = true;
+		}
 		state.evXmlBeginTime = firstNoteBeginTime ? firstNoteBeginTime / 1000 : xmlNum ? 60 / state.originSpeed * xmlNum * 4/denNum : 0;
 		state.secondEvXmlBeginTime = firstNoteBeginTime ? 0 : xmlNum2 ? 60 / state.originSpeed * xmlNum2 * 4/denNum2 : 0;
 		const hasTimeGap = xmlParse.getElementsByTagName("timegap").length > 0;

+ 1 - 1
src/page-instrument/header-top/settting/index.tsx

@@ -92,7 +92,7 @@ export default defineComponent({
                                 <div class={styles.tit}>唱名类型</div>
                                 <div class={styles.radioBox}>
                                     {
-                                        [{name:'男生',value:1}, {name:'女生',value:0}].map(item=>{
+                                        [{name:'男声',value:1}, {name:'女声',value:0}].map(item=>{
                                             return <div class={ audioData.mingSongType===item.value && styles.active } onClick={ ()=>{ 
                                                 if(audioData.mingSongType === item.value){
                                                     return

+ 2 - 2
src/page-instrument/view-detail/index.tsx

@@ -440,9 +440,9 @@ export default defineComponent({
     );
     // 监听跟练的开启状态
     watch(
-      () => followData.start,
+      () => followData.practiceStart,
       () => {
-        headerColumnHide.value = followData.start;
+        headerColumnHide.value = followData.practiceStart;
       }
     );
     // 监听开始评测状态

+ 10 - 2
src/page-instrument/view-detail/smoothAnimation/index.ts

@@ -468,9 +468,17 @@ function drawLines(context: CanvasRenderingContext2D, pointsPos: pointsPosType,
    context.lineWidth = 2
    context.strokeStyle = color
    context.beginPath()
-   context.moveTo(pointsPos[0].x, pointsPos[0].y)
+   // 记录上一个实际绘制的点
+   let lastDrawnPoint = pointsPos[0]
+   context.moveTo(lastDrawnPoint.x, lastDrawnPoint.y)
    for (let i = 1; i < pointsPos.length; i++) {
-      context.lineTo(pointsPos[i].x, pointsPos[i].y)
+      const currPoint = pointsPos[i]
+      const distance = Math.hypot(currPoint.x - lastDrawnPoint.x, currPoint.y - lastDrawnPoint.y)
+      // 如果两个点之间的距离大于阈值,才进行绘制
+      if (distance > 2) {
+         context.lineTo(currPoint.x, currPoint.y)
+         lastDrawnPoint = currPoint // 更新上一个实际绘制的点
+      }
    }
    context.stroke()
 }

+ 2 - 0
src/state.ts

@@ -439,6 +439,8 @@ const state = reactive({
   secondEvXmlBeginTime: 0,
   /** evxml等待播放的时间集合,多遍反复播放,会有多个timegap(前奏)时间 */
   evXmlBeginArr: [] as any,
+  /** evxml的曲子是否有times */
+  xmlHasTimes: false,
   /** 指法信息 */
   fingeringInfo: {} as IFingering,
   /** 滚动容器的ID */

+ 1 - 1
src/view/audio-list/index.tsx

@@ -190,7 +190,7 @@ export const changeSongSourceByBate = (isDisBate:boolean) => {
 		audioData.mingSongEle && (audioData.mingSongEle.muted = false);
 	}
 }
-/** 切换男生女生唱名  */
+/** 切换男声女声唱名  */
 export const changeMingSongType = () =>{
 	// 当有男声女声都有值时候才能切换 
 	const { mingSongEle, mingSongGirlEle, beatMingSongEle, beatMingSongGirlEle } = audioData.mingSongTypeCollection

+ 13 - 10
src/view/follow-practice/index.tsx

@@ -115,21 +115,24 @@ export const handleFollowStart = async () => {
 		followData.practiceStart = false;
 	} else {
 		followData.dontAccredit = false;
-		// 跟练模式开始前,增加播放系统节拍器
-		const tickend = await handleStartTick();
-		// console.log("🚀 ~ tickend:", tickend)
-		// 节拍器返回false, 取消播放
-		if (!tickend) {
-			followData.isBeginMask = false
-			followData.start = false;
-			followData.practiceStart = false;
-			return false;
+		// 从头开始跟练,跟练模式开始前,增加播放系统节拍器
+		if (state.activeNoteIndex === 0) {
+			const tickend = await handleStartTick();
+			// console.log("🚀 ~ tickend:", tickend)
+			// 节拍器返回false, 取消播放
+			if (!tickend) {
+				followData.isBeginMask = false
+				followData.start = false;
+				followData.practiceStart = false;
+				return false;
+			}
 		}
 		onClear();
 		followData.isBeginMask = false
 		followData.start = true;
 		followData.practiceStart = true;
-		followData.index = 0;
+		// followData.index = 0;
+		followData.index = state.activeNoteIndex;
 		followData.list = [];
 		initSetPlayRate();
 		resetPlaybackToStart();

BIN
src/view/selection/imgs/pitchHigh.png


BIN
src/view/selection/imgs/pitchLow.png


+ 44 - 30
src/view/selection/index.module.less

@@ -158,44 +158,58 @@
     }
 }
 
+// .followTipUp, .followTipDown {
+//     display: flex;
+//     align-items: center;
+//     background: rgba(0,0,0,0.75);
+//     position: relative;
+//     padding: 6px 10px;
+//     border-radius: 16px;
+//     width: fit-content;
+//     left: 50%;
+//     top: -42px;
+//     transform: translate(-50%);
+//     img {
+//         width: 18px;
+//         height: 18px;
+//         margin-right: 6px;
+//     }
+//     span {
+//         font-size: 14px;
+//         font-weight: 500;
+//         color: #fff;
+//         word-break: keep-all;
+//         display: flex;
+//         width: fit-content;
+//     }
+//     ::before {
+//         content: "";
+//         position: absolute;
+//         left: 50%;
+//         bottom: -8PX;
+//         transform: translateX(-50%);
+//         width: 13Px;
+//         height: 9Px;
+//         background-image: url('./imgs/arrow_icon.png');
+//         background-size: 100% 100%;
+//         background-position: center center;
+//         background-repeat: no-repeat;
+//         z-index: 2;    
+//         opacity: 0.7;
+//     }
+// }
+
 .followTipUp, .followTipDown {
     display: flex;
     align-items: center;
-    background: rgba(0,0,0,0.75);
     position: relative;
-    padding: 6px 10px;
-    border-radius: 16px;
     width: fit-content;
     left: 50%;
     top: -42px;
     transform: translate(-50%);
-    img {
-        width: 18px;
-        height: 18px;
-        margin-right: 6px;
-    }
-    span {
-        font-size: 14px;
-        font-weight: 500;
-        color: #fff;
-        word-break: keep-all;
-        display: flex;
-        width: fit-content;
-    }
-    ::before {
-        content: "";
-        position: absolute;
-        left: 50%;
-        bottom: -8PX;
-        transform: translateX(-50%);
-        width: 13Px;
-        height: 9Px;
-        background-image: url('./imgs/arrow_icon.png');
-        background-size: 100% 100%;
-        background-position: center center;
-        background-repeat: no-repeat;
-        z-index: 2;    
-        opacity: 0.7;
+    > img {
+        width: auto;
+        height: 30px;
     }
 }
 

+ 4 - 4
src/view/selection/index.tsx

@@ -8,8 +8,8 @@ import { Icon, showToast } from "vant";
 import MoveMusicScore, { moveData, renderForMoveData } from "../plugins/move-music-score";
 import { useRoute } from "vue-router";
 import { getQuery } from "/src/utils/queryString";
-import IntonationDown from "./imgs/down_icon.png"
-import IntonationUp from "./imgs/up_icon.png"
+import IntonationDown from "./imgs/pitchLow.png"
+import IntonationUp from "./imgs/pitchHigh.png"
 import MultipleRestMeasures from "./multipleRestMeasures"
 
 const selectData = reactive({
@@ -371,11 +371,11 @@ export default defineComponent({
 									<Icon name="cross" /> */}
 									<div class={[styles.followTipUp, 'tip-up']}>
 										<img src={IntonationUp} />
-										<span>音准<i>高了</i></span>
+										{/* <span>音准<i>高了</i></span> */}
 									</div>
 									<div class={[styles.followTipDown, 'tip-down']}>
 										<img src={IntonationDown} />
-										<span>音准<i>低了</i></span>
+										{/* <span>音准<i>低了</i></span> */}
 									</div>
 								</div>							
 								<div class={[styles.noteDot, 'node-dot']}></div>