Browse Source

管乐团按钮状态统一

liushengqiang 1 year ago
parent
commit
46c1f9fa76

+ 15 - 13
src/page-orchestra/custom-plugins/guide-page/index.tsx

@@ -34,19 +34,21 @@ export default defineComponent({
 			if (search.questionId || search.lessonTrainingId) {
 				return;
 			}
-			guideData.tip1 = !localStorage.getItem("isFirstTip");
-			if (guideData.tip1) {
-				guideData.tip1 = true;
-				guideData.tip2 = false;
-				tipShow.value = true;
-				return;
-			}
-			guideData.tip2 = !localStorage.getItem("isFirstModel");
-			// console.log("🚀 ~ guideData.tip2:", guideData.tip2);
-			if (guideData.tip2 && !headData.modeMode) {
-				guideData.tip1 = false;
-				guideData.tip2 = true;
-				tipShow.value = true;
+			if (headData.modeMode) {
+				guideData.tip1 = !localStorage.getItem("isFirstTip");
+				if (guideData.tip1) {
+					guideData.tip1 = true;
+					guideData.tip2 = false;
+					tipShow.value = true;
+					return;
+				}
+			} else {
+				guideData.tip2 = !localStorage.getItem("isFirstModel");
+				if (guideData.tip2 && state.modeType === "practise") {
+					guideData.tip1 = false;
+					guideData.tip2 = true;
+					tipShow.value = true;
+				}
 			}
 		};
 		onMounted(() => {

+ 19 - 18
src/page-orchestra/follow-model/index.tsx

@@ -3,11 +3,26 @@ import styles from "./index.module.less";
 import icons from "./icons.json";
 import { handleFollowEnd, handleFollowStart } from "/src/view/follow-practice";
 
+const startBtn = ref(false);
+const endBtn = ref(false);
+
+/** 开始跟练 */
+const hanlde_startFollow = () => {
+	startBtn.value = false;
+	endBtn.value = true;
+	handleFollowStart();
+};
+
+/** 停止跟练 */
+export const handle_stopFollow = () => {
+	startBtn.value = true;
+	endBtn.value = false;
+	handleFollowEnd();
+};
+
 export default defineComponent({
 	name: "follow-model",
 	setup() {
-		const startBtn = ref(false);
-		const endBtn = ref(false);
 		onMounted(() => {
 			startBtn.value = true;
 		});
@@ -19,28 +34,14 @@ export default defineComponent({
 				<Transition name="pop-center">
 					{startBtn.value && (
 						<div class={styles.startBtn} key="start">
-							<img
-								src={icons.start}
-								onClick={() => {
-									startBtn.value = false;
-									endBtn.value = true;
-									handleFollowStart();
-								}}
-							/>
+							<img src={icons.start} onClick={hanlde_startFollow} />
 						</div>
 					)}
 				</Transition>
 				<Transition name="pop-center">
 					{endBtn.value && (
 						<div class={styles.endBtn} key="end">
-							<img
-								src={icons.end}
-								onClick={() => {
-									startBtn.value = true;
-                                    endBtn.value = false;
-									handleFollowEnd();
-								}}
-							/>
+							<img src={icons.end} onClick={handle_stopFollow} />
 						</div>
 					)}
 				</Transition>

+ 1 - 5
src/page-orchestra/header-top/index.module.less

@@ -62,10 +62,6 @@
             width: 85%;
             height: 85%;
         }
-
-        &.disabled {
-            opacity: .8;
-        }
     }
 
     .badge {
@@ -111,7 +107,7 @@
     }
 }
 
-.disable {
+.disabled {
     pointer-events: none;
     opacity: .6;
 }

+ 190 - 50
src/page-orchestra/header-top/index.tsx

@@ -1,25 +1,28 @@
-import { computed, defineComponent, onBeforeUnmount, onMounted, reactive, ref } from "vue";
+import { computed, defineComponent, onBeforeUnmount, onMounted, reactive, ref, watch } from "vue";
 import styles from "./index.module.less";
+import store from 'store'
 
 import Title from "./title";
 import icons from "./image/headerTop.json";
 import { Badge, Circle, Popover, Popup } from "vant";
 import { metronomeData } from "../../helpers/metronome";
 import Speed from "./speed";
-import { handleEndBegin, handleStartEvaluat } from "/src/view/evaluating";
+import { evaluatingData, handleEndBegin, handleStartEvaluat } from "/src/view/evaluating";
 import Settting from "./settting";
 import ModeTypeMode from "./mode-type-mode";
 import state, { handleChangeSection, handleResetPlay, handleRessetState, togglePlay } from "/src/state";
 import { getAudioCurrentTime } from "/src/view/audio-list";
-import { toggleFollow } from "/src/view/follow-practice";
+import { followData, toggleFollow } from "/src/view/follow-practice";
 import { api_back, api_suspendPlay } from "/src/helpers/communication";
 import MusicType from "./music-type";
 import { handleNoEndExit } from "../custom-plugins/recording-time";
+import { handle_stopFollow } from "../follow-model";
 
 export const headData = reactive({
 	speedShow: false,
 	musicTypeShow: false,
 	modeMode: true, // 模式弹框
+	settingMode: false, // 设置弹框
 });
 
 /** 关闭模式选择 */
@@ -30,43 +33,147 @@ export const handleCloseModeMode = (type = false) => {
 export default defineComponent({
 	name: "header-top",
 	setup() {
-		const headerData = reactive({
-			settingMode: false,
-		});
-		const headRef = ref();
-
-		const toggleEvaluat = () => {
-			handleStartEvaluat();
-		};
 
 		/** 切换模式 */
 		const handleChangeModeType = (value: "practise" | "follow" | "evaluating") => {
 			if (value === "evaluating") {
-				toggleEvaluat();
+				handleStartEvaluat();
 			} else if (value === "follow") {
 				toggleFollow();
 			}
 			headData.modeMode = false;
 		};
-		const disabledList = ["evaluating"];
 
-		/** 按钮禁用 */
+		/** 设置按钮 */
+		const settingBtn = computed(() => {
+			// 音频播放中 禁用
+			if (state.playState === "play") return { display: true, disabled: true };
+			// 评测开始 禁用, 跟练开始 禁用
+			if (evaluatingData.startBegin || followData.start) return { display: true, disabled: true };
 
-		/** 重播按钮显示条件 */
-		const resetBtnDisplay = computed(() => {
-			const currentTime = getAudioCurrentTime();
-			const playState = state.playState;
-			const modeType = state.modeType;
-			return currentTime !== 0 && playState !== "play" && modeType === "practise";
+			return {
+				display: true,
+				disabled: false,
+			};
+		});
+
+		/** 转谱按钮 */
+		const converBtn = computed(() => {
+			// 音频播放中 禁用
+			if (state.playState === "play") return { display: true, disabled: true };
+			// 评测开始 禁用
+			if (evaluatingData.startBegin || followData.start) return { display: true, disabled: true };
+
+			return {
+				disabled: false,
+				display: true,
+			};
+		});
+
+		/** 速度按钮 */
+		const speedBtn = computed(() => {
+			// 选择模式 不显示
+			if (headData.modeMode) return { display: false, disabled: false };
+			// 音频播放中 禁用
+			if (state.playState === "play") return { display: true, disabled: true };
+			// 评测模式 禁用
+			if (state.modeType === "evaluating") return { display: true, disabled: true };
+			// 跟练模式 不显示
+			if (state.modeType === "follow") return { display: false, disabled: true };
+
+			return {
+				disabled: false,
+				display: true,
+			};
 		});
-		/** 播放按钮显示条件 */
-		const playBtnDisplay = computed(() => {
-			const modeType = state.modeType;
-			return modeType === "practise";
+
+		/** 指法按钮 */
+		const fingeringBtn = computed(() => {
+			// 没有指法 不显示
+			if (!state.fingeringInfo.name) return { display: false, disabled: true };
+			// 选择模式 不显示
+			if (headData.modeMode) return { display: false, disabled: false };
+			// 音频播放中 禁用
+			if (state.playState === "play") return { display: true, disabled: true };
+			// 评测模式 不显示,跟练模式 不显示
+			if (["evaluating", "follow"].includes(state.modeType)) return { display: false, disabled: true };
+
+			return {
+				disabled: false,
+				display: true,
+			};
+		});
+
+		/** 选段按钮 */
+		const selectBtn = computed(() => {
+			// 选择模式 不显示
+			if (headData.modeMode) return { display: false, disabled: false };
+			// 音频播放中 禁用
+			if (state.playState === "play") return { display: true, disabled: true };
+			// 评测模式 不显示,跟练模式 不显示
+			if (["evaluating", "follow"].includes(state.modeType)) return { display: false, disabled: true };
+
+			return {
+				disabled: false,
+				display: true,
+			};
 		});
-		/** 指法显示条件 */
-		const fingeringDisplay = computed(() => {
-			return state.fingeringInfo.name;
+
+		/** 原声按钮 */
+		const originBtn = computed(() => {
+			// 选择模式 不显示
+			if (headData.modeMode) return { display: false, disabled: false };
+			// 跟练模式 不显示
+			if (state.modeType === "follow") return { display: false, disabled: true };
+			// 评测开始 禁用
+			if (state.modeType === "evaluating") return { display: true, disabled: true };
+
+			return {
+				disabled: false,
+				display: true,
+			};
+		});
+
+		/** 模式切换按钮 */
+		const toggleBtn = computed(() => {
+			// 选择模式 不显示
+			if (headData.modeMode) return { display: false, disabled: false };
+			// 跟练开始 禁用
+			if (followData.start) return { display: true, disabled: true };
+
+			return {
+				display: true,
+				disabled: false,
+			};
+		});
+
+		/** 播放按钮 */
+		const playBtn = computed(() => {
+			// 选择模式 不显示
+			if (headData.modeMode) return { display: false, disabled: false };
+			// 评测模式 不显示,跟练模式 不显示
+			if (["evaluating", "follow"].includes(state.modeType)) return { display: false, disabled: true };
+
+			return {
+				display: true,
+				disabled: false,
+			};
+		});
+
+		/** 重播按钮 */
+		const resetBtn = computed(() => {
+			// 选择模式 不显示
+			if (headData.modeMode) return { display: false, disabled: false };
+			// 评测模式 不显示,跟练模式 不显示
+			if (["evaluating", "follow"].includes(state.modeType)) return { display: false, disabled: true };
+			// 播放进度为0 不显示, 不是暂停状态不显示
+			const currentTime = getAudioCurrentTime();
+			if (currentTime === 0 || state.playState !== "paused") return { display: false, disabled: true };
+
+			return {
+				display: true,
+				disabled: false,
+			};
 		});
 
 		/** 返回 */
@@ -77,25 +184,34 @@ export default defineComponent({
 
 		onMounted(() => {
 			api_suspendPlay(() => {
-				if (state.modeType === 'practise') {
-					togglePlay('paused')
-				} else if (state.modeType === 'evaluating'){
-					handleEndBegin()
+				if (state.modeType === "practise") {
+					togglePlay("paused");
+				} else if (state.modeType === "evaluating") {
+					handleEndBegin();
+				} else if (state.modeType === "follow") {
+					handle_stopFollow();
 				}
-			})
-		})
+			});
+		});
+
+		// 设置改变触发
+		watch(state.setting, () => {
+			store.set("musicscoresetting", state.setting);
+		});
 
 		return () => (
-			<div ref={headRef} class={styles.headerTop}>
+			<div class={styles.headerTop}>
 				<div class={styles.back} onClick={handleBack}>
 					<img src={icons["icon-back"]} />
 				</div>
 				<Title text={state.examSongName} rightView={false} />
 
-				<div class={styles.headRight} style={{ display: headData.modeMode ? "none" : "" }}>
+				<div class={styles.headRight}>
+					{/* 模式切换按钮 */}
 					<div
 						id="tips-step-0"
-						class={styles.btn}
+						style={{ display: toggleBtn.value.display ? "" : "none" }}
+						class={[styles.btn, toggleBtn.value.disabled && styles.disabled]}
 						onClick={() => {
 							handleRessetState();
 							headData.modeMode = true;
@@ -105,9 +221,11 @@ export default defineComponent({
 						<span>模式</span>
 					</div>
 
+					{/* 原声按钮 */}
 					<div
 						id="tips-step-1"
-						class={[styles.btn, disabledList.includes(state.modeType) && styles.disable]}
+						style={{ display: originBtn.value.display ? "" : "none" }}
+						class={[styles.btn, originBtn.value.disabled && styles.disabled]}
 						onClick={() => {
 							state.playSource = state.playSource === "music" ? "background" : "music";
 						}}
@@ -115,14 +233,23 @@ export default defineComponent({
 						<img class={styles.iconBtn} src={state.playSource === "music" ? icons.music : icons.accompaniment} />
 						<span>{state.playSource === "music" ? "原声" : "伴奏"}</span>
 					</div>
-					<div id="tips-step-2" class={[styles.btn, disabledList.includes(state.modeType) && styles.disable]} onClick={() => handleChangeSection()}>
+
+					{/* 选段按钮 */}
+					<div
+						id="tips-step-2"
+						style={{ display: selectBtn.value.display ? "" : "none" }}
+						class={[styles.btn, selectBtn.value.disabled && styles.disabled]}
+						onClick={() => handleChangeSection()}
+					>
 						<img class={styles.iconBtn} src={state.section.length === 0 ? icons.section : state.section.length === 1 ? icons.section1 : icons.section2} />
 						<span>选段</span>
 					</div>
+
+					{/* 指法按钮 */}
 					<div
 						id="tips-step-3"
-						style={{ display: fingeringDisplay.value ? "" : "none" }}
-						class={[styles.btn, disabledList.includes(state.modeType) && styles.disable]}
+						style={{ display: fingeringBtn.value.display ? "" : "none" }}
+						class={[styles.btn, fingeringBtn.value.disabled && styles.disabled]}
 						onClick={() => {
 							state.setting.displayFingering = !state.setting.displayFingering;
 						}}
@@ -152,12 +279,14 @@ export default defineComponent({
 						<span style={{ whiteSpace: "nowrap" }}>节拍器</span>
 					</div> */}
 
+					{/* 速度按钮 */}
 					<Popover trigger="manual" v-model:show={headData.speedShow} placement="bottom" overlay={false}>
 						{{
 							reference: () => (
 								<div
 									id="tips-step-4"
-									class={[styles.btn, disabledList.includes(state.modeType) && styles.disable]}
+									style={{ display: speedBtn.value.display ? "" : "none" }}
+									class={[styles.btn, speedBtn.value.disabled && styles.disabled]}
 									onClick={(e: Event) => {
 										e.stopPropagation();
 										headData.speedShow = !headData.speedShow;
@@ -172,11 +301,14 @@ export default defineComponent({
 							default: () => <Speed />,
 						}}
 					</Popover>
+
+					{/* 转简谱按钮 */}
 					<Popover trigger="manual" v-model:show={headData.musicTypeShow} placement="bottom-end" overlay={false}>
 						{{
 							reference: () => (
 								<div
-									class={[styles.btn, disabledList.includes(state.modeType) && styles.disable]}
+									style={{ display: converBtn.value.display ? "" : "none" }}
+									class={[styles.btn, converBtn.value.disabled && styles.disabled]}
 									onClick={(e: Event) => {
 										e.stopPropagation();
 										headData.musicTypeShow = !headData.musicTypeShow;
@@ -190,14 +322,20 @@ export default defineComponent({
 						}}
 					</Popover>
 
-					<div class={[styles.btn, disabledList.includes(state.modeType) && styles.disable]} onClick={() => (headerData.settingMode = true)}>
+					{/* 设置按钮 */}
+					<div
+						style={{ display: settingBtn.value.display ? "" : "none" }}
+						class={[styles.btn, settingBtn.value.disabled && styles.disabled]}
+						onClick={() => (headData.settingMode = true)}
+					>
 						<img class={styles.iconBtn} src={icons.setting} />
 						<span>设置</span>
 					</div>
 
+					{/* 播放按钮 */}
 					<div
-						style={{ display: playBtnDisplay.value ? "" : "none" }}
-						class={[styles.btn, styles.playBtn, disabledList.includes(state.modeType) && styles.disable]}
+						style={{ display: playBtn.value.display ? "" : "none" }}
+						class={[styles.btn, styles.playBtn, playBtn.value.disabled && styles.disabled]}
 						id="tips-step-5"
 						onClick={() => togglePlay()}
 					>
@@ -213,9 +351,11 @@ export default defineComponent({
 							/>
 						</div>
 					</div>
+
+					{/* 重播按钮 */}
 					<div
-						style={{ display: resetBtnDisplay.value ? "" : "none" }}
-						class={[styles.btn, styles.resetBtn, disabledList.includes(state.modeType) && styles.disable]}
+						style={{ display: resetBtn.value.display ? "" : "none" }}
+						class={[styles.btn, styles.resetBtn, resetBtn.value.disabled && styles.disabled]}
 						id="tips-step-7"
 						onClick={() => handleResetPlay()}
 					>
@@ -223,10 +363,10 @@ export default defineComponent({
 					</div>
 				</div>
 
-				<Popup v-model:show={headerData.settingMode} class="popup-custom van-scale" transition="van-scale" teleport="body">
-					<Settting onClose={() => (headerData.settingMode = false)} />
+				<Popup v-model:show={headData.settingMode} class="popup-custom van-scale" transition="van-scale" teleport="body">
+					<Settting onClose={() => (headData.settingMode = false)} />
 				</Popup>
-				<Popup v-model:show={headData.modeMode}  teleport="body" class="popup-custom" position="bottom" closeOnClickOverlay={false} overlay={false}>
+				<Popup v-model:show={headData.modeMode} teleport="body" class="popup-custom" position="bottom" closeOnClickOverlay={false} overlay={false}>
 					<ModeTypeMode onClose={(value) => handleChangeModeType(value)} />
 				</Popup>
 			</div>

+ 0 - 5
src/page-orchestra/header-top/settting/index.tsx

@@ -10,7 +10,6 @@ import iconTv from "../image/tv.png";
 import iconYijian from "../image/yijian.png";
 import ScreenModel from "../../custom-plugins/helper-model/screen-model";
 import Recommendation from "../../custom-plugins/helper-model/recommendation";
-import store from 'store'
 
 export default defineComponent({
 	name: "header-settting",
@@ -20,10 +19,6 @@ export default defineComponent({
 			show: false,
 			recommendationShow: false, // 建议
 		});
-		// 设置改变触发
-		watch(state.setting, () => {
-			store.set('musicscoresetting', state.setting)
-		})
 		return () => (
 			<div class={styles["header-settting"]}>
 				<div class={styles.closeBtn} onClick={() => emit("close")}>

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

@@ -41,6 +41,7 @@ export const evaluatingData = reactive({
 	earphoneMode: false, // 耳机弹窗
 	soundEffectMode: false, // 效音弹窗
 	websocketState: false, // websocket连接状态
+	/**是否开始播放 */
 	startBegin: false, // 开始
 	backtime: 0, // 延迟时间
 	/** 已经评测的数据 */

+ 3 - 3
src/view/follow-practice/index.tsx

@@ -106,14 +106,14 @@ const onFollowTime = (evt?: IPostMessage) => {
 
 /** 在渲染前后计算光标应该走到的音符 */
 const setStep = () => {
+	if (!followData.start) {
+		return;
+	}
 	let startTime = Date.now();
 	requestAnimationFrame(() => {
 		const endTime = Date.now();
 		// 渲染时间大于16.6,就会让页面卡顿, 如果渲染时间大与16.6就下一个渲染帧去计算
 		if (endTime - startTime < 16.6) {
-			if (!followData.start) {
-				return;
-			}
 			checked();
 		}
 		setStep();