123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375 |
- 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 { 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 { 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, // 设置弹框
- });
- /** 关闭模式选择 */
- export const handleCloseModeMode = (type = false) => {
- headData.modeMode = type;
- };
- export default defineComponent({
- name: "header-top",
- setup() {
- /** 切换模式 */
- const handleChangeModeType = (value: "practise" | "follow" | "evaluating") => {
- if (value === "evaluating") {
- handleStartEvaluat();
- } else if (value === "follow") {
- toggleFollow();
- }
- headData.modeMode = false;
- };
- /** 设置按钮 */
- const settingBtn = computed(() => {
- // 音频播放中 禁用
- if (state.playState === "play") return { display: true, disabled: true };
- // 评测开始 禁用, 跟练开始 禁用
- if (evaluatingData.startBegin || followData.start) return { display: true, disabled: true };
- 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 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 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,
- };
- });
- /** 返回 */
- const handleBack = () => {
- handleNoEndExit();
- api_back();
- };
- onMounted(() => {
- api_suspendPlay(() => {
- 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 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}>
- {/* 模式切换按钮 */}
- <div
- id="tips-step-0"
- style={{ display: toggleBtn.value.display ? "" : "none" }}
- class={[styles.btn, toggleBtn.value.disabled && styles.disabled]}
- onClick={() => {
- handleRessetState();
- headData.modeMode = true;
- }}
- >
- <img class={styles.iconBtn} src={icons.modelType} />
- <span>模式</span>
- </div>
- {/* 原声按钮 */}
- <div
- id="tips-step-1"
- style={{ display: originBtn.value.display ? "" : "none" }}
- class={[styles.btn, originBtn.value.disabled && styles.disabled]}
- onClick={() => {
- state.playSource = state.playSource === "music" ? "background" : "music";
- }}
- >
- <img class={styles.iconBtn} src={state.playSource === "music" ? icons.music : icons.accompaniment} />
- <span>{state.playSource === "music" ? "原声" : "伴奏"}</span>
- </div>
- {/* 选段按钮 */}
- <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: fingeringBtn.value.display ? "" : "none" }}
- class={[styles.btn, fingeringBtn.value.disabled && styles.disabled]}
- onClick={() => {
- state.setting.displayFingering = !state.setting.displayFingering;
- }}
- >
- <img class={styles.iconBtn} src={state.setting.displayFingering ? icons.fingeringOn : icons.fingeringOff} />
- <span>指法</span>
- </div>
- {/* <div
- class={[styles.btn]}
- onClick={async () => {
- metronomeData.lineShow = !metronomeData.lineShow;
- }}
- >
- <img class={styles.iconBtn} src={headImg("iconStep.png")} />
- <span>{metronomeData.lineShow ? "高级" : "初级"}</span>
- </div> */}
- {/* <div
- class={styles.btn}
- onClick={async () => {
- metronomeData.disable = !metronomeData.disable;
- metronomeData.metro?.initPlayer();
- }}
- >
- <img style={{ display: metronomeData.disable ? "block" : "none" }} class={styles.iconBtn} src={headImg("tickoff.png")} />
- <img style={{ display: !metronomeData.disable ? "block" : "none" }} class={styles.iconBtn} src={headImg("tickon.png")} />
- <span style={{ whiteSpace: "nowrap" }}>节拍器</span>
- </div> */}
- {/* 速度按钮 */}
- <Popover trigger="manual" v-model:show={headData.speedShow} placement="bottom" overlay={false}>
- {{
- reference: () => (
- <div
- id="tips-step-4"
- style={{ display: speedBtn.value.display ? "" : "none" }}
- class={[styles.btn, speedBtn.value.disabled && styles.disabled]}
- onClick={(e: Event) => {
- e.stopPropagation();
- headData.speedShow = !headData.speedShow;
- }}
- >
- <Badge class={styles.badge} content={state.speed}>
- <img class={styles.iconBtn} src={icons.speed} />
- </Badge>
- <span>速度</span>
- </div>
- ),
- default: () => <Speed />,
- }}
- </Popover>
- {/* 转简谱按钮 */}
- <Popover trigger="manual" v-model:show={headData.musicTypeShow} placement="bottom-end" overlay={false}>
- {{
- reference: () => (
- <div
- style={{ display: converBtn.value.display ? "" : "none" }}
- class={[styles.btn, converBtn.value.disabled && styles.disabled]}
- onClick={(e: Event) => {
- e.stopPropagation();
- headData.musicTypeShow = !headData.musicTypeShow;
- }}
- >
- <img class={styles.iconBtn} src={icons["icon-zhuanpu"]} />
- <span>转简谱</span>
- </div>
- ),
- default: () => <MusicType />,
- }}
- </Popover>
- {/* 设置按钮 */}
- <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: playBtn.value.display ? "" : "none" }}
- class={[styles.btn, styles.playBtn, playBtn.value.disabled && styles.disabled]}
- id="tips-step-5"
- onClick={() => togglePlay()}
- >
- <div class={styles.btnWrap}>
- <img class={styles.iconBtn} src={state.playState === "paused" ? icons.play : icons.pause} />
- <Circle
- style={{ display: state.playState === "paused" ? "none" : "" }}
- class={styles.progress}
- stroke-width={80}
- currentRate={state.playProgress}
- rate={100}
- color="#FFC830"
- />
- </div>
- </div>
- {/* 重播按钮 */}
- <div
- style={{ display: resetBtn.value.display ? "" : "none" }}
- class={[styles.btn, styles.resetBtn, resetBtn.value.disabled && styles.disabled]}
- id="tips-step-7"
- onClick={() => handleResetPlay()}
- >
- <img class={styles.iconBtn} src={icons["reset"]} />
- </div>
- </div>
- <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}>
- <ModeTypeMode onClose={(value) => handleChangeModeType(value)} />
- </Popup>
- </div>
- );
- },
- });
|