Bläddra i källkod

feat: 一行谱页面

TIANYONG 1 år sedan
förälder
incheckning
be5cbf00e3

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

@@ -52,7 +52,11 @@ export default defineComponent({
                         <div class={styles.cellBox}>
                             <div class={styles.tit}>延迟检测</div>
                             <Switch v-model={state.setting.soundEffect}></Switch>
-                        </div>                       
+                        </div>   
+                        <div class={styles.cellBox}>
+                            <div class={styles.tit}>摄像头</div>
+                            <Switch v-model={state.setting.camera}></Switch>
+                        </div>                                              
                         <div class={styles.cellBox}>
                             <div class={styles.tit}>标准音高</div>
                             <div class={styles.frequency}>

+ 7 - 2
src/page-instrument/simple-detail/index.module.less

@@ -12,11 +12,12 @@
 
 .detail {
     width: 100vw;
-    height: 100vh;
+    height: auto;
     overflow: hidden;
     overflow-y: auto;
     --header-height: 62px;
-    background: var(--container-background);
+    // background: var(--container-background);
+    background: transparent;
 
     .container {
         margin: 0 10px;
@@ -30,5 +31,9 @@
             height: initial !important;
             max-height: initial !important;
         }
+        .smoothAnimationBox {
+            height: 0 !important;
+            overflow: hidden;
+        }
     }
 }

+ 83 - 4
src/page-instrument/simple-detail/index.tsx

@@ -1,18 +1,24 @@
 import { defineComponent, onMounted, onUnmounted, reactive } from "vue";
-import state, { getMusicDetail } from "/src/state";
+import state, { getMusicDetail, handleSetSpeed, addNoteBBox, getNote, gotoNext } from "/src/state";
 import MusicScore from "../../view/music-score";
 import styles from "./index.module.less";
 import { getQuery } from "/src/utils/queryString";
 import { closeToast, showLoadingToast } from "vant";
-
+import store from "store";
+import { formateTimes } from "../../helpers/formateMusic";
+import { setCustomGradual, setCustomNoteRealValue } from "/src/helpers/customMusicScore"
+import { initSmoothAnimation, smoothAnimationState, destroySmoothAnimation, moveSmoothAnimationByPlayTime } from "../view-detail/smoothAnimation";
+import { api_playProgress } from "/src/helpers/communication";
 
 export default defineComponent({
-	name: "music-list",
+	name: "simple-detail",
 	setup() {
 		const query: any = getQuery();
 
 		const detailData = reactive({
 			isLoading: true,
+			currentTime: 0, // 当前播放的时间
+			totalTime: 60000, // 音视频总时长
 		});
 
 		const communicateCb = (res: any) => {
@@ -24,6 +30,15 @@ export default defineComponent({
 				}
 			}
 		};
+		// 监听评测曲谱音频播放进度,返回
+		const progress = (res: any) => {
+			detailData.currentTime = res?.currentTime || res?.content?.currentTime;
+			detailData.totalTime = res?.totalDuration || res?.content?.totalDuration;
+			const time = detailData.currentTime / 1000;
+			if (res?.content?.totalDuration > 1000 && detailData.currentTime >= detailData.totalTime) {
+				// 播放结束
+			}
+		};
 
 		onMounted(async () => {
 			const id = query.id || '';
@@ -31,6 +46,7 @@ export default defineComponent({
 			detailData.isLoading = false;
 			state.isSingleLine = true;
 			state.isSimplePage = true;
+			api_playProgress(progress);
 			window.addEventListener("message", communicateCb);
 		});
 
@@ -39,8 +55,71 @@ export default defineComponent({
 			window.removeEventListener("message", communicateCb);
 		});
 		/** 渲染完成 */
-		const handleRendered = async () => {
+		const handleRendered = async (osmd: any) => {
 			console.log('渲染完成')
+			state.osmd = osmd;
+			// 没有设置速度使用读取的速度
+			if (state.originSpeed === 0) {
+				state.originSpeed = state.speed = (osmd as any).bpm || osmd.Sheet.userStartTempoInBPM || 100;
+			}
+			const saveSpeed = (store.get("speeds") || {})[state.examSongId] || state.speed || (osmd as any).bpm || osmd.Sheet.userStartTempoInBPM;
+			// 加载本地缓存的速度
+			if (saveSpeed) {
+				handleSetSpeed(saveSpeed);
+			}
+			setCustomGradual();
+			setCustomNoteRealValue();
+			state.times = formateTimes(osmd);
+			console.log("🚀 ~ state.times:", state.times, state.subjectId, state);
+			// 音符添加位置信息bbox
+			addNoteBBox(state.times);
+			// 一行谱创建 动画
+			initSmoothAnimation();
+			//destroySmoothAnimation();
+			smoothAnimationState.isShow.value = false;
+			state.playState = 'play';
+			setStep();
+		};
+		/**
+		 * 播放一直触发的事件
+		 */
+		const handlePlaying = () => {
+			detailData.currentTime += 0.03;
+			const currentTime = detailData.currentTime;
+			const duration = detailData.totalTime;
+			state.playProgress = (currentTime / duration) * 100;
+			// console.log('👀~播放进度',currentTime)
+			let item = getNote(currentTime);
+			if (item) {
+				gotoNext(item);
+			}
+			// 一行谱,需要滚动小节
+			if (state.isSingleLine) {
+				moveSmoothAnimationByPlayTime(currentTime)
+			}
+		
+		};
+		/** 在渲染前后计算光标应该走到的音符 */
+		const setStep = () => {
+			// console.log('播放状态',state.playState)
+			if (state.playState !== "play") {
+				console.log("暂停播放");
+				return;
+			}
+			let startTime = Date.now();
+			requestAnimationFrame(() => {
+			const endTime = Date.now();
+			// 渲染时间大于16.6,就会让页面卡顿, 如果渲染时间大与16.6就下一个渲染帧去计算
+			if (endTime - startTime < 16.7) {
+				handlePlaying();
+				setStep();
+			} else {
+				setTimeout(() => {
+				handlePlaying();
+				setStep();
+				}, 16.7);
+			}
+			});
 		};
 
 		return () => (

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

@@ -112,12 +112,12 @@ export function destroySmoothAnimation() {
 /**
  * 根据播放时间进度移动处理
  */
-export function moveSmoothAnimationByPlayTime() {
+export function moveSmoothAnimationByPlayTime(time?: number) {
    // 暂停之后不进行移动了
    if (state.playState === "paused") {
       return
    }
-   const currentTime = getAudioCurrentTime()
+   const currentTime = time || getAudioCurrentTime()
    if (currentTime <= state.fixtime) return
    if (currentTime > state.times.last()?.endtime) return
    // 当休止小节,可能当前音符在谱面上没有实际的音符(没有bbox),所以往后找谱面上有的音符
@@ -159,6 +159,7 @@ export function moveSmoothAnimation(progress: number, activeIndex: number) {
    // // 当前的index
    let nowIndex = nextPointsIndex - _numberOfSegments + progressCalcIndex
    // 当前计算的位置和上一次值一样时候不运行
+   console.log('移动000',moveState.oldIndex,nowIndex)
    if (moveState.oldIndex === nowIndex) {
       return
    }
@@ -175,6 +176,7 @@ export function moveSmoothAnimation(progress: number, activeIndex: number) {
       smoothAnimationState.pointsPos.slice(0, nowIndex)
    )
    // 当移动到屏幕最右边时候 就不进行移动了
+   console.log('移动1111',(smoothAnimationState.osdmScrollDom?.scrollLeft || 0) + smoothAnimationState.translateXNum + smoothAnimationState.osdmScrollDomWith,smoothAnimationState.canvasDomWith)
    if (
       (smoothAnimationState.osdmScrollDom?.scrollLeft || 0) + smoothAnimationState.translateXNum + smoothAnimationState.osdmScrollDomWith >=
       smoothAnimationState.canvasDomWith

+ 1 - 1
src/state.ts

@@ -954,7 +954,7 @@ export const getNote = (currentTime: number) => {
   const times = state.times;
   const len = state.times.length;
   /** 播放超过了最后一个音符的时间,直接结束, 2秒误差 */
-  if (currentTime > times[len - 1].endtime + 2 && !state.isAppPlay) {
+  if (currentTime > times[len - 1].endtime + 2 && !state.isAppPlay && !state.isSimplePage) {
     onEnded();
     return;
   }

+ 2 - 1
src/view/music-score/index.module.less

@@ -17,7 +17,8 @@
         //     transform-origin: left top;
         // }
         #osmdCanvasPage1{
-            //position: absolute !important;
+            // position: absolute !important;
+            width: fit-content;
             left: 0;
             top: 0;
         }

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

@@ -203,7 +203,7 @@ export default defineComponent({
 				]}
 			>
 				{slots.default?.()}
-				{props.showSelection && musicData.showSelection && !state.isPreView && !state.isEvaluatReport && <Selection />}
+				{props.showSelection && musicData.showSelection && !state.isPreView && !state.isEvaluatReport &&!state.isSimplePage && <Selection />}
 			</div>
 		);
 	},