Selaa lähdekoodia

Merge branch 'feature-tianyong-newVersion' into feature-wxl-newVersion

lex 11 kuukautta sitten
vanhempi
commit
71d84ead92

BIN
src/assets/DIN_Alternate_Bold.ttf


+ 7 - 2
src/helpers/customMusicScore.ts

@@ -592,14 +592,19 @@ const transSinglePage = () => {
 	if (state.isSingleLine && !state.isSimplePage) {
 		const svgPage = document?.getElementById('osmdSvgPage1')?.getBoundingClientRect();
 		const staffLine = document?.querySelector('.staffline')?.getBoundingClientRect();
-		if (svgPage && staffLine && svgPage.height > 130) {
+		if (svgPage && staffLine && svgPage.height > 200 && state.platform !== 'PC') {
 			// 需要上移的距离
-			console.log('need',svgPage.height,staffLine.height)
+			// console.log('need',svgPage.height,staffLine.height)
 			const rate = svgPage.height > 400 ? 1.2 : 2;
 			const needTransTop = (svgPage.height - staffLine.height) / rate;
 			// @ts-ignore
 			document.getElementById('osmdSvgPage1').style.transform = `translateY(-${needTransTop}px)`;
 			// document.querySelector('.staffline').style.transform = `translateY(-${needTransTop}px)`;
+			// const musicLine =  document.querySelector('.staffline').querySelector('.vf-measure').querySelector('.vf-custom-bg').getBoundingClientRect();
+			// const needTransDistance = svgPage.height / 2 - (musicLine.top - svgPage.top)
+			// console.log('svg移动距离',needTransDistance)
+			// // @ts-ignore
+			// document.getElementById('osmdSvgPage1').style.transform = `translateY(${needTransDistance}px)`
 		}
 	}
 }

+ 0 - 2
src/page-instrument/component/authorName/index.module.less

@@ -1,7 +1,5 @@
 .authorName{
     height: 1.8rem;
-    position: relative;
-    top: 36px;
 }
 .title{
     width: 280px;

+ 3 - 0
src/page-instrument/custom-plugins/helper-model/recommendation/index.module.less

@@ -177,6 +177,9 @@
                             font-size: 14px;
                             color: #AAAAAA;
                         }
+                        &::-webkit-scrollbar {
+                            display: none;
+                        }
                     }
                 }
             }

+ 8 - 3
src/page-instrument/evaluat-model/evaluat-result/index.module.less

@@ -98,6 +98,7 @@
         .scoreSection {
             display: flex;
             align-items: flex-end;
+            justify-content: center;
         }
 
         .text {
@@ -105,8 +106,6 @@
             position: relative;
             display: flex;
             align-items: flex-end;
-            font-family: DIN-Bold, DIN;
-            font-weight: bold;
             font-weight: 600;
             font-size: 22px;
             color: #FF5510;
@@ -142,6 +141,7 @@
             margin-right: 2px;
             margin-bottom: -2px;
             font-size: 38px;
+            font-family: DIN-Bold, DIN;
         }
 
         .rightBadge {
@@ -306,10 +306,15 @@
         font-weight: 500;
         font-size: 18px;
         color: #FF5510;
-        line-height: 25px;
+        display: flex;
+        align-items: flex-end;
+        line-height: 1;
         .scores{
             font-size: 14px;
         }
+        .scoresNum{
+            font-family: DIN-Bold, DIN;
+        }
     }
 
 }

+ 3 - 3
src/page-instrument/evaluat-model/evaluat-result/index.tsx

@@ -148,21 +148,21 @@ export default defineComponent({
                       <img src={yzImg} />
                       <span>音准</span>
                     </div>
-                    <div>{evaluatingData.resultData.intonation}<span class={styles.scores}>分</span></div>
+                    <div><span class={styles.scoresNum}>{evaluatingData.resultData.intonation}</span><span class={styles.scores}>分</span></div>
                   </div>
                   <div class={styles.progressitem}>
                     <div>
                       <img src={jzImg} />
                       <span>节奏</span>
                     </div>
-                    <div>{evaluatingData.resultData.cadence}<span class={styles.scores}>分</span></div>
+                    <div><span class={styles.scoresNum}>{evaluatingData.resultData.cadence}</span><span class={styles.scores}>分</span></div>
                   </div>
                   <div class={styles.progressitem}>
                     <div>
                       <img src={wzxImg} />
                       <span>完成度</span>
                     </div>
-                    <div>{evaluatingData.resultData.integrity}<span class={styles.scores}>分</span></div>
+                    <div><span class={styles.scoresNum}>{evaluatingData.resultData.integrity}</span><span class={styles.scores}>分</span></div>
                   </div>
                 </div>
               )}

+ 14 - 4
src/page-instrument/evaluat-model/index.tsx

@@ -140,8 +140,14 @@ export default defineComponent({
         // const erji = await checkUseEarphone();
         const res = await getEarphone();
         const erji = res?.content?.checkIsWired || false;
-        console.log("耳机状态111", res);
-        evaluatingData.earphoneMode = true;
+        // 是否已经提示过耳机弹窗,重新进入评测页面,重置该状态为false,手动关掉耳机弹窗,改变该状态为true,本次评测都不在提示耳机状态弹窗
+        if (!evaluatingData.onceErjiPopShow) {
+          evaluatingData.earphoneMode = true;
+        } else {
+          clearTimeout(checkErjiTimer);
+          checkErjiTimer = null;
+          return;
+        }
         evaluatingData.earPhoneType = res?.content?.type || "";
         if (evaluatingData.earPhoneType === "有线耳机") {
           clearTimeout(checkErjiTimer);
@@ -303,7 +309,7 @@ export default defineComponent({
         speed: evaluatSpeed,
         heardLevel: state.setting.evaluationDifficulty,
         // beatLength: Math.round((state.fixtime * 1000) / rate),
-        beatLength: actualBeatLength,
+        beatLength: actualBeatLength / rate,
         evaluationCriteria: state.evaluationStandard,
         speedRate: parseFloat(rate.toFixed(2)), // 播放倍率
       };
@@ -506,7 +512,10 @@ export default defineComponent({
         await api_startDelayCheck({});
       } else {
         evaluatingData.checkEnd = true;
-        checkEarphoneStatus();
+        // 点击评测模式进入评测模块的需要检测耳机状态,通过返回按钮进入评测模块的,不检测耳机状态
+        if (evaluatingData.needCheckErjiStatus) {
+          checkEarphoneStatus();
+        }
       }
       evaluatingData.isDisabledPlayMusic = true;
       // handlePerformDetection();
@@ -587,6 +596,7 @@ export default defineComponent({
           <Earphone
             earphoneType={evaluatingData.earPhoneType}
             onClose={() => {
+              evaluatingData.onceErjiPopShow = true;
               clearTimeout(checkErjiTimer);
               checkErjiTimer = null;
               // #11035,可能刚好关闭耳机弹窗的时候,第二次又出现了弹窗

+ 12 - 11
src/page-instrument/follow-model/microphone/index.module.less

@@ -54,19 +54,20 @@
         height: 60%;
         transform: translateX(-50%);
     }
-    .microCancel {
+    .microBtn {
         position: absolute;
-        bottom: 85px;
-        left: 39.5%;
-        width: 91px;
-        height: 39px;
+        bottom: 23.5%;
+        left: 50%;
+        transform: translate(-45%);
+    }
+    .microCancel {
+        width: 11.2vw;
+        height: 100%;
+        margin-right: 2px;
     }
     .microConfirm {
-        position: absolute;
-        bottom: 85px;
-        right: 28.5%;
-        transform: translateX(-80%);
-        width: 91px;
-        height: 39px;
+        width: 11.2vw;
+        height: 100%;
+        margin-left: 2px;
     }
 }

+ 4 - 2
src/page-instrument/follow-model/microphone/index.tsx

@@ -14,8 +14,10 @@ export default defineComponent({
 		return () => (
 			<div class={styles.microBox}>
 				<img class={styles.microBg} src={microBg} />
-				<img class={styles.microCancel} src={microCancel} onClick={() => emit("close")} />
-				<img class={styles.microConfirm} src={microConfirm} onClick={() => emit("close")} />
+				<div class={styles.microBtn}>
+					<img class={styles.microCancel} src={microCancel} onClick={() => emit("close")} />
+					<img class={styles.microConfirm} src={microConfirm} onClick={() => emit("close")} />
+				</div>
 			</div>
 		);
 	},

+ 4 - 1
src/page-instrument/header-top/index.module.less

@@ -281,6 +281,7 @@
             top: -9px;
             display: flex;
             align-items: center;
+            justify-content: center;
             background: #FFC121;
             border-radius: 120px 120px 120px 1px;
             border: 1px solid #FFFFFF;
@@ -423,10 +424,12 @@
 
     .modeBox {
         width: 100%;
-        margin-top: 90px;
         display: flex;
         justify-content: space-between;
         padding: 0 36px;
+        position: relative;
+        top: 50%;
+        transform: translateY(-50%);
 
         &.twoModeBox {
             justify-content: center;

+ 7 - 1
src/page-instrument/header-top/modeView.tsx

@@ -110,6 +110,8 @@ export default defineComponent({
             smoothAnimationState.isShow.value = state.melodyLine;
             // 返回的时候 跳转到之前记录的模式
             if(headTopData.oldModeType !== "practise"){
+              // 点击评测模式进入评测模块的需要检测耳机状态,通过返回按钮进入评测模块的,不检测耳机状态
+              evaluatingData.needCheckErjiStatus = false;
               headTopData.handleChangeModeType(headTopData.oldModeType)
             }
             headTopData.modeType = "show";
@@ -122,7 +124,11 @@ export default defineComponent({
             headTopData.handleChangeModeType("practise")
             } }></Vue3Lottie>
           {!state.isPercussion && <Vue3Lottie ref={modeImgDom2} class={styles.modeImg} animationData={glMode} autoPlay={false} loop={true} onClick={() => headTopData.handleChangeModeType("follow")}></Vue3Lottie>}
-          {state.enableEvaluation && <Vue3Lottie ref={modeImgDom3} class={styles.modeImg} animationData={pcMode} autoPlay={false} loop={true} onClick={() => headTopData.handleChangeModeType("evaluating")}></Vue3Lottie>}
+          {state.enableEvaluation && <Vue3Lottie ref={modeImgDom3} class={styles.modeImg} animationData={pcMode} autoPlay={false} loop={true} onClick={() => {
+            // 点击评测模式进入评测模块的需要检测耳机状态,通过返回按钮进入评测模块的,不检测耳机状态
+            evaluatingData.needCheckErjiStatus = true;
+            headTopData.handleChangeModeType("evaluating")
+          }}></Vue3Lottie>}
         </div>
         {data.showVip && <TheVip />}
         {/** 延迟检测中途,socket出错,网络提示弹窗 */}

+ 2 - 2
src/page-instrument/header-top/speed/index.tsx

@@ -66,7 +66,7 @@ export default defineComponent({
 			  if (storeData.isApp && state.enableEvaluation) {
 				// 加载弹窗的开始时间
 				let startTime = +new Date();
-				state.loadingText = '节拍器准备中,请稍等…'
+				state.loadingText = res ? '节拍器准备中,请稍等…' : '节拍器关闭中,请稍等…';
 				state.isLoading = true;
 				const targetSrc = res ? state.beatSong.accompany || state.beatSong.music : state.accompany || state.music;
 				const resData = await api_updateMusicPlayer({
@@ -89,7 +89,7 @@ export default defineComponent({
 							state.isLoading = false;
 							metronomeDisable.value = res;
 							switchLoading.value = false;
-						}, continueTime);
+						}, 1200);
 					}
 				}
 				// api_checkSocketStatus();

+ 38 - 27
src/page-instrument/view-detail/index.module.less

@@ -80,17 +80,19 @@
 
     .container {
         position: sticky;
-        top: 36px;
-        height: calc(100vh - 36px);
+        top: 0;
+        height: 100vh;
         border-radius: 10px;
         transition: height .2s;
         transition: padding-bottom .2s;
         overflow: hidden;
-    }
 
-    .multiContainer {
-        top: 0;
-        height: calc(100vh);
+        :global {
+            #musicAndSelection {
+                // 其他位置 这个高度留白是36,这里加了一点,让旋律线靠下一点
+                padding-top: 40px;
+            }
+        }
     }
 
     .pcContainer {
@@ -264,28 +266,37 @@
     z-index: 10000;
     background: rgba(0, 0, 0, .6);
 
-    .lottie {
-        width: 120px;
-    }
+    <<<<<<< HEAD .lottie {
+        =======&.isPreView {
+            background: transparent;
 
-    .loadingTip {
-        font-size: 14px;
-        color: #fff;
+            .loadingTip {
+                color: #999;
+            }
+        }
+
+        .lottie {
+            >>>>>>>feature-tianyong-newVersion width: 120px;
+        }
+
+        .loadingTip {
+            font-size: 14px;
+            color: #fff;
+        }
     }
-}
 
-.bg2Left {
-    width: 52px;
-    height: 125px;
-    position: absolute;
-    left: 0;
-    top: 0;
-}
+    .bg2Left {
+        width: 52px;
+        height: 125px;
+        position: absolute;
+        left: 0;
+        top: 0;
+    }
 
-.bg2Right {
-    width: 52px;
-    height: 125px;
-    position: absolute;
-    right: 0;
-    top: 0;
-}
+    .bg2Right {
+        width: 52px;
+        height: 125px;
+        position: absolute;
+        right: 0;
+        top: 0;
+    }

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

@@ -271,8 +271,8 @@ export default defineComponent({
       handleInitTick(osmd?.Sheet?.SheetPlaybackSetting?.Rhythm?.Numerator || 4);
       // }
       // api_cloudLoading();
-      state.playBtnDirection = query.imagePos === "left" ? "left" : "right";
-      state.isAttendClass = query.imagePos === "left" || query.imagePos === "right" ? true : false;
+      // state.playBtnDirection = query.imagePos === 'left' ? 'left' : 'right';
+      // state.isAttendClass = (query.imagePos === 'left' || query.imagePos === 'right') ? true : false;
       // if (state.fingeringInfo.direction === "vertical" && state.setting.displayFingering) {
       //   state.musicScoreBtnDirection = state.playBtnDirection === 'right' ? 'left' : 'right';
       // } else {
@@ -331,7 +331,7 @@ export default defineComponent({
                 height: state.fingeringInfo.name === "hulusi-flute" ? "86%" : "80%",
                 right: state.playBtnDirection === "right" ? "initial" : 0,
                 left: state.playBtnDirection === "right" ? 0 : "initial",
-                top: state.fingeringInfo.name === "ocarina" ? "60px" : 0,
+                top: state.fingeringInfo.name === "ocarina" || state.fingeringInfo.name === "whistling" ? "60px" : 0,
               },
             };
           } else {
@@ -344,7 +344,7 @@ export default defineComponent({
                 width: state.fingeringInfo.width,
                 height: state.fingeringInfo.name === "hulusi-flute" ? "86%" : "80%",
                 left: 0,
-                top: state.fingeringInfo.name === "ocarina" ? "60px" : 0,
+                top: state.fingeringInfo.name === "ocarina" || state.fingeringInfo.name === "whistling" ? "60px" : 0,
               },
             };
           }
@@ -494,7 +494,7 @@ export default defineComponent({
         <div
           id="scrollContainer"
           style={{ ...fingerConfig.value.container }}
-          class={[styles.container, !state.setting.displayCursor && "hideCursor", browsInfo.xiaomi && styles.xiaomi, state.platform === IPlatform.PC && styles.pcContainer, (!state.isSingleLine || state.isCombineRender) && styles.multiContainer]}
+          class={[styles.container, !state.setting.displayCursor && "hideCursor", browsInfo.xiaomi && styles.xiaomi, state.platform === IPlatform.PC && styles.pcContainer]}
           onClick={(e: Event) => {
             e.stopPropagation();
             // if (state.playState === "play" && state.platform != IPlatform.PC) {

+ 1 - 1
src/page-instrument/view-detail/loading.tsx

@@ -18,7 +18,7 @@ export default defineComponent({
    setup(props) {
       return () =>
          (
-            <div class={styles.loadingPop} style={{display:state.isLoading? "flex" : "none"}}>
+            <div class={[styles.loadingPop, state.isPreView && styles.isPreView]} style={{display:state.isLoading? "flex" : "none"}}>
                <img class={styles.lottie} src={animGif} />
                {/* <Vue3Lottie class={styles.lottie} animationData={animBg}></Vue3Lottie> */}
                <div class={styles.loadingTip}>{props.tipText}</div>

+ 20 - 17
src/page-instrument/view-detail/smoothAnimation/index.ts

@@ -187,7 +187,7 @@ export function moveSmoothAnimation(progress: number, activeIndex: number, isMov
  */
 function move_osmd(nowPointsPos: pointsPosType[0]) {
    // 评测移动太快看不到前面小节的分数,评测改成0.5倍速移动谱面
-   const speed = (state.modeType === 'evaluating' ? smoothAnimationState.aveSpeed * 0.5 : smoothAnimationState.aveSpeed) * (state.speed / 60)
+   const speed = (state.modeType === "evaluating" ? smoothAnimationState.aveSpeed * 0.5 : smoothAnimationState.aveSpeed) * (state.speed / 60)
    // 视口宽度
    const clientWidth = smoothAnimationState.osdmScrollDomWith
    const clientMidWidth = clientWidth / 2
@@ -316,27 +316,20 @@ function createSmoothAnimation() {
  * 根据音符获取坐标
  */
 function getPointsPosByBatePos(): pointsPosType {
-   let totalAvInde = 0
-   // 取平均值
-   const totalAv =
-      state.times.reduce((total, item) => {
-         if (item.frequency !== -1) {
-            // -1 为休止符
-            total += item.frequency
-            totalAvInde++
-         }
-         return total
-      }, 0) / totalAvInde
-   const pointsPos = state.times.reduce((posArr: any[], item) => {
+   // 得到音符频率数据
+   const frequencyData = state.times.map(item => {
+      return !item.frequency || item.frequency === -1 ? 0 : item.frequency
+   })
+   console.log(frequencyData,"没线性化之前的数据")
+   // 线性频率数据
+   const frequencyLineData = quantileScale(frequencyData, 4, 76)
+   const pointsPos = state.times.reduce((posArr: any[], item, index) => {
       // 当休止小节,可能当前音符在谱面上没有实际的音符(没有bbox),所以往后找谱面上有的音符
       if (item.bbox) {
          posArr.push({
             MeasureNumberXML: item.MeasureNumberXML,
             x: item.bbox.x,
-            // 当为休止符的时候 取最下面的位置*0.9,确保能显示完整
-            y:
-               smoothAnimationState.canvasDomHeight / 2 -
-               ((((item.frequency === -1 ? 2 * totalAv * 0.1 : item.frequency) - totalAv) / totalAv) * smoothAnimationState.canvasDomHeight) / 2
+            y: 80 - frequencyLineData[index]
          })
       }
       return posArr
@@ -352,6 +345,16 @@ function getPointsPosByBatePos(): pointsPosType {
    return pointsPos
 }
 
+// 数据平滑算法
+function quantileScale(data: number[], minRange = 0, maxRange = 80) {
+   const sortedData = [...data].sort((a, b) => a - b)
+   return data.map(value => {
+      const rank = sortedData.indexOf(value) / (sortedData.length - 1)
+      const scaledValue = rank * (maxRange - minRange) + minRange
+      return Math.max(minRange, Math.min(scaledValue, maxRange))
+   })
+}
+
 /**
  * 使用传入的曲线的顶点坐标创建平滑曲线的顶点。
  * @param  {Array}   points  曲线顶点坐标数组,

+ 9 - 1
src/page-instrument/view-evaluat-report/component/share-top/index.module.less

@@ -160,6 +160,11 @@
     }
 }
 
+.padMiddle {
+    .cItem {
+        width: 50px;
+    }
+}
 .right {
     display: flex;
     align-items: center;
@@ -326,7 +331,10 @@
             }
         }
     }
-
+    &.padPlayerBox{
+        width: 418px;
+        height: 248px;
+    }
     .videoBox {
         width: 100%;
         height: 100%;

+ 7 - 2
src/page-instrument/view-evaluat-report/component/share-top/index.tsx

@@ -81,6 +81,11 @@ export default defineComponent({
       return "video";
     });
 
+    // 资源类型
+    const isPad = computed(() => {
+      return navigator?.userAgent?.includes("UAWEIVRD-W09") || browserInfo?.iPad;
+    });
+
 		const openAudioAndVideo = () => {
 			shareData.show = true;
 			if (shareData.isInitPlyr) return;
@@ -231,7 +236,7 @@ export default defineComponent({
 
           {/* 音准、节奏、完整度纬度 */}
 
-          <div class={styles.middle}>
+          <div class={[styles.middle, isPad.value && styles.padMiddle]}>
             {state.isPercussion ? null : (
               <div onClick={() => handleChange("intonation")} class={[styles.cItem, "evaluting-report-1", itemType.value === "intonation" && styles.active]}>
                 <span class={styles.mScore}>{scoreData.value.intonation}分</span>
@@ -434,7 +439,7 @@ export default defineComponent({
               shareData._plrl?.pause();
             }}
           >
-            <div class={styles.playerBox}>
+            <div class={[styles.playerBox, isPad.value && styles.padPlayerBox]}>
               {mediaType.value === "audio" ? (
                 <div class={styles.audioBox}>
                   <canvas class={styles.audioVisualizer} id="audioVisualizer"></canvas>

+ 3 - 1
src/state.ts

@@ -1355,7 +1355,7 @@ function xmlToTracks(xmlString: string) {
 // 设置音源
 function initMusicSource(data: any, tracks: string[], partIndex: number) {
   let track:string,index:number
-  const { instrumentId } = storeData.user
+  const instrumentId = query.instrumentId || storeData.user?.instrumentId
   let { musicSheetType, isAllSubject, musicSheetSoundList, musicSheetAccompanimentList } = data
   musicSheetSoundList || (musicSheetSoundList = [])
   musicSheetAccompanimentList || (musicSheetAccompanimentList = [])
@@ -1665,6 +1665,8 @@ const setState = (data: any, index: number) => {
   } else {
     state.setting.frequency = state.setting.frequency || state.baseFrequency
   }
+  state.playBtnDirection = query.imagePos === 'left' ? 'left' : 'right';
+  state.isAttendClass = (query.imagePos === 'left' || query.imagePos === 'right') ? true : false;
 };
 
 // 多分轨合并显示标示

+ 5 - 0
src/style.css

@@ -195,3 +195,8 @@ body {
 html {
   font-size: 64px;
 }
+
+@font-face {
+  font-family: "DIN-1Bold";
+  src: url("./assets/DIN_Alternate_Bold.ttf");
+}

+ 3 - 1
src/view/evaluating/index.tsx

@@ -114,6 +114,8 @@ export const evaluatingData = reactive({
   needReplayEvaluat: false, // 手动取消评测,需要自动开始评测
   needPlayTick: false, // 评测时,mp3节拍器需要等待音频开始播放后再执行播放节拍器的圆点动画
   tipErjiShow: false, // 评测提示弹窗
+  onceErjiPopShow: false, // 是否已经提示过耳机弹窗,重新进入评测页面,重置该状态为false,手动关掉耳机弹窗,改变该状态为true,本次评测都不在提示耳机状态弹窗
+  needCheckErjiStatus: true, // 点击评测模式进入评测模块的需要检测耳机状态,通过返回按钮进入评测模块的,不检测耳机状态
 });
 
 const sendOffsetTime = async (offsetTime: number) => {
@@ -785,7 +787,7 @@ export default defineComponent({
       // evaluatingData.resulstMode = true;
       // evaluatingData.resultData = {...getLeveByScore(10), score: 10, intonation: 10, cadence: 30, integrity: 40}
       // console.log("🚀 ~ evaluatingData.resultData:", evaluatingData.resultData)
-
+      evaluatingData.onceErjiPopShow = false;
       evaluatingData.evaluatings = {};
       evaluatingData.soundEffectFrequency = 0;
       evaluatingData.checkStep = 0;

+ 1 - 0
src/view/music-score/index.tsx

@@ -104,6 +104,7 @@ export default defineComponent({
 				// drawMetronomeMarks: false,
 				// ...this.opotions,
 				colorStemsLikeNoteheads: true, // 是否将音符柄的颜色设置为与它们的音符头相同,默认false
+				// drawingParameters: "compact" // 使用紧凑布局
 			});
 			// osmd.EngravingRules.CompactMode = true // 紧凑模式
 			// osmd.EngravingRules.PageRightMargin = state.isSingleLine ? (window.innerWidth+200)/10 : 2;

+ 10 - 7
src/view/plugins/toggleMusicSheet/choosePartName/index.tsx

@@ -1,4 +1,4 @@
-import { PropType, computed, defineComponent, ref, toRefs, onMounted, watch } from 'vue'
+import { PropType, computed, defineComponent, ref, toRefs, onMounted, watch, nextTick } from 'vue'
 import { Picker, Button, Icon } from 'vant'
 import styles from './index.module.less'
 import state, { IPlatform } from "/src/state";
@@ -76,12 +76,15 @@ export default defineComponent({
               }}
             />
             <div class={styles.button} onClick={() => {
-                // console.log(1111,selectIndex.value)
-                if (partIndexChanged.value) {
-                  emit('close', selectIndex.value)
-                } else {
-                  emit('close', partIndex.value)
-                }
+                myPicker.value.confirm()
+                nextTick(()=>{
+                  // console.log(1111,selectIndex.value)
+                  if (partIndexChanged.value) {
+                    emit('close', selectIndex.value)
+                  } else {
+                    emit('close', partIndex.value)
+                  }
+                })
               }
             }></div>
           </div>

+ 10 - 9
src/view/selection/index.module.less

@@ -161,7 +161,7 @@
 .followTipUp, .followTipDown {
     display: flex;
     align-items: center;
-    background: rgba(0,0,0,0.6);
+    background: rgba(0,0,0,0.7);
     position: relative;
     padding: 6px 10px;
     border-radius: 16px;
@@ -298,16 +298,17 @@
     // background: #07c160;
 }
 
-.staveBg {
-    &::before {
-        content: "";
+// 阴影
+.staveBgContainer{
+    position: absolute;
+    left: 0;
+    top: 0;
+    right: 0;
+    z-index: -100;
+    .staveBg{
         position: absolute;
-        left: 0;
-        bottom: -3Px;
-        width: 100%;
-        height: 8Px;
+        height: 8px !important;
         background: linear-gradient(rgba(7, 24, 56, 0.5) 0%, #010D31 100%);
-        z-index: 0;
         filter: blur(5Px);
         opacity: 0.7;
     }

+ 155 - 133
src/view/selection/index.tsx

@@ -260,145 +260,167 @@ export default defineComponent({
 			} catch (error) {}
 		});
 		return () => (
-			<div
-				id="selectionBox"
-				class={[
-					styles.selectionContainer,
-				]}
-				onClick={(e: Event) => e.stopPropagation()}
-			>
-				{selectData.staves.map((item: any) => {
-					// 评测得分
-					const scoreItem = item.id && evaluatingData.evaluatings[item.measureListIndex];
-					// for(let idx in evaluatingData.evaluatings) {
-					// 	const { show, measureIndex } = evaluatingData.evaluatings[idx]
-					// 	if (show && measureIndex !== item.measureListIndex) {
-					// 		evaluatingData.evaluatings[idx].show = false
-					// 	}
-					// }
-					// 高级模式下,显示节拍线
-					// 不是报告模式
-					// 不是多小节休止符
-					// 节拍线开关
-					// 当前小节
-					// 当前小节
-					const lineShow =
-						!state.isReport &&
-						metronomeData.cursorMode === 2 &&
-						item.MeasureNumberXML === metronomeData.activeMetro?.measureNumberXML &&
-						state.times[state.activeNoteIndex].MeasureNumberXML === item.MeasureNumberXML;
-					return (
-						<>
-							{item.staveBox && (
-								<div
-									class={[
-										styles.position,
-										// scoreItem ? `scoreItemLeve${scoreItem.leve}` : "", // 去掉评测小节得分的背景色
-										item.multipleRestMeasures <= 1 ? styles.staveBg : "",
-										(state.platform === IPlatform.PC && state.zoom > 0.8) ? styles.linePC : '',
-									]}
-									style={item.staveBox}
-									onClick={() => handleSelection(item)}
-								>
-									{lineShow && (
-										<div style={{height: selectData.measureHeight + 'px', position: 'relative'}}>
+			<>
+				<div class={styles.staveBgContainer}>
+					{
+						selectData.staves.map((item: any) => {
+							return (
+								<>
+									{
+										item.staveBox && item.multipleRestMeasures <= 1 && 
 											<div 
-											class={[
-												styles.line,
-												state.setting.eyeProtection ? styles.eyeLine : '',
-												state.musicRenderType == EnumMusicRenderType.staff ? styles.lineStaff : styles.lineJianPu,
-											]} 
-											style={{ left: metronomeData.activeMetro.left }}></div>
-										</div>
-									)}
-									{!state.isReport &&
-										!!item.multipleRestMeasures &&
-										state.activeMeasureIndex == item.MeasureNumberXML && (
-											<div class={styles.dotWrap}>{item.multipleRestMeasures}</div>
-										)}
-									<Transition
-										name="centerTop"
-										onAfterEnter={() => {
-											scoreItem.show = false;
-										}}
+												style={{
+													left:item.staveBox.left,
+													top:`calc(${item.staveBox.top} + ${item.staveBox.height})`,
+													width:item.staveBox.width
+												}}
+												class={[styles.staveBg]}
+											></div>
+									}
+								</>
+							)
+						})
+					}
+				</div>
+				<div
+					id="selectionBox"
+					class={[
+						styles.selectionContainer,
+					]}
+					onClick={(e: Event) => e.stopPropagation()}
+				>
+					{selectData.staves.map((item: any) => {
+						// 评测得分
+						const scoreItem = item.id && evaluatingData.evaluatings[item.measureListIndex];
+						// for(let idx in evaluatingData.evaluatings) {
+						// 	const { show, measureIndex } = evaluatingData.evaluatings[idx]
+						// 	if (show && measureIndex !== item.measureListIndex) {
+						// 		evaluatingData.evaluatings[idx].show = false
+						// 	}
+						// }
+						// 高级模式下,显示节拍线
+						// 不是报告模式
+						// 不是多小节休止符
+						// 节拍线开关
+						// 当前小节
+						// 当前小节
+						const lineShow =
+							!state.isReport &&
+							metronomeData.cursorMode === 2 &&
+							item.MeasureNumberXML === metronomeData.activeMetro?.measureNumberXML &&
+							state.times[state.activeNoteIndex].MeasureNumberXML === item.MeasureNumberXML;
+						return (
+							<>
+								{item.staveBox && (
+									<div
+										class={[
+											styles.position,
+											// scoreItem ? `scoreItemLeve${scoreItem.leve}` : "", // 去掉评测小节得分的背景色
+											(state.platform === IPlatform.PC && state.zoom > 0.8) ? styles.linePC : '',
+										]}
+										style={item.staveBox}
+										onClick={() => handleSelection(item)}
 									>
-										{scoreItem?.show && (
-											<div
-												class={styles.scoreItem}
-												style={{ color: leveByScoreMeasureIcons[scoreItem.leve]?.color || "" }}
-											>
-												<img src={leveByScoreMeasureIcons[scoreItem.leve]?.icon} />
-												<span>{scoreItem.score}</span>
+										{lineShow && (
+											<div style={{height: selectData.measureHeight + 'px', position: 'relative'}}>
+												<div 
+												class={[
+													styles.line,
+													state.setting.eyeProtection ? styles.eyeLine : '',
+													state.musicRenderType == EnumMusicRenderType.staff ? styles.lineStaff : styles.lineJianPu,
+												]} 
+												style={{ left: metronomeData.activeMetro.left }}></div>
 											</div>
 										)}
-									</Transition>
-								</div>
-							)}
-						</>
-					);
-				})}
-				{selectData.notes.map((item: any) => {
-					return (
-						<div
-							class={[styles.position, disableClickNote.value && styles.disable, styles.note, `noteIndex_${item.index}`]}
-							style={item.bbox}
-							onClick={() => skipNotePlay(item.index)}
-						>
-							{/* <div class={styles.noteFollow} data-vf={"vf" + item.id}>
-								<Icon name="success" />
-								<Icon name="cross" />
-							</div> */}
-							<div class={styles.noteFollow} data-vf={"vf" + item.id}>
-								{/* <Icon name="success" />
-								<Icon name="cross" /> */}
-								<div class={[styles.followTipUp, 'tip-up']}>
-									<img src={IntonationUp} />
-									<span>音准<i>高了</i></span>
-								</div>
-								<div class={[styles.followTipDown, 'tip-down']}>
-									<img src={IntonationDown} />
-									<span>音准<i>低了</i></span>
-								</div>
-							</div>							
-							<div class={[styles.noteDot, 'node-dot']}></div>
-						</div>
-					);
-				})}
-				{/* 选段 */}
-				{
-					sectionPosData.value.map((item,index) =>{
+										{!state.isReport &&
+											!!item.multipleRestMeasures &&
+											state.activeMeasureIndex == item.MeasureNumberXML && (
+												<div class={styles.dotWrap}>{item.multipleRestMeasures}</div>
+											)}
+										<Transition
+											name="centerTop"
+											onAfterEnter={() => {
+												scoreItem.show = false;
+											}}
+										>
+											{scoreItem?.show && (
+												<div
+													class={styles.scoreItem}
+													style={{ color: leveByScoreMeasureIcons[scoreItem.leve]?.color || "" }}
+												>
+													<img src={leveByScoreMeasureIcons[scoreItem.leve]?.icon} />
+													<span>{scoreItem.score}</span>
+												</div>
+											)}
+										</Transition>
+									</div>
+								)}
+							</>
+						);
+					})}
+					{selectData.notes.map((item: any) => {
 						return (
-							item && <div class={styles.selectBox} style={item}>
-								<div class={[styles.selectHandle,index>0&&styles.selectHandleRight,(state.playState==="play" || query.workRecord)&&styles.playIng]} onClick={()=>{
-									// 如果选择了2个 删除左边的时候
-									if(state.section.length===2&&index === 0){
-										state.section = []
-										// 重置速度和播放倍率
-										resetBaseRate(state.activeNoteIndex);
-										showToast({
-											message: "请选择开始小节",
-											duration: 0,
-											position: "top",
-											className: "selectionToast",
-										});
-									}else{
-										state.section.splice(index,1)
-										state.section = [...state.section]  // 触发 watch
-										showToast({
-											message: state.section.length?"请选择结束小节":"请选择开始小节",
-											duration: 0,
-											position: "top",
-											className: "selectionToast",
-										});
-									}
-								}}></div>
+							<div
+								class={[styles.position, disableClickNote.value && styles.disable, styles.note, `noteIndex_${item.index}`]}
+								style={item.bbox}
+								onClick={() => skipNotePlay(item.index)}
+							>
+								{/* <div class={styles.noteFollow} data-vf={"vf" + item.id}>
+									<Icon name="success" />
+									<Icon name="cross" />
+								</div> */}
+								<div class={styles.noteFollow} data-vf={"vf" + item.id}>
+									{/* <Icon name="success" />
+									<Icon name="cross" /> */}
+									<div class={[styles.followTipUp, 'tip-up']}>
+										<img src={IntonationUp} />
+										<span>音准<i>高了</i></span>
+									</div>
+									<div class={[styles.followTipDown, 'tip-down']}>
+										<img src={IntonationDown} />
+										<span>音准<i>低了</i></span>
+									</div>
+								</div>							
+								<div class={[styles.noteDot, 'node-dot']}></div>
 							</div>
-						)
-					})
-				}
-				{/* 移动模块 */}
-				{query.isMove == "1" && <MoveMusicScore />}
-			</div>
+						);
+					})}
+					{/* 选段 */}
+					{
+						sectionPosData.value.map((item,index) =>{
+							return (
+								item && <div class={styles.selectBox} style={item}>
+									<div class={[styles.selectHandle,index>0&&styles.selectHandleRight,(state.playState==="play" || query.workRecord)&&styles.playIng]} onClick={()=>{
+										// 如果选择了2个 删除左边的时候
+										if(state.section.length===2&&index === 0){
+											state.section = []
+											// 重置速度和播放倍率
+											resetBaseRate(state.activeNoteIndex);
+											showToast({
+												message: "请选择开始小节",
+												duration: 0,
+												position: "top",
+												className: "selectionToast",
+											});
+										}else{
+											state.section.splice(index,1)
+											state.section = [...state.section]  // 触发 watch
+											showToast({
+												message: state.section.length?"请选择结束小节":"请选择开始小节",
+												duration: 0,
+												position: "top",
+												className: "selectionToast",
+											});
+										}
+									}}></div>
+								</div>
+							)
+						})
+					}
+					{/* 移动模块 */}
+					{query.isMove == "1" && <MoveMusicScore />}
+				</div>
+			</>
 		);
 	},
 });