123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128 |
- import { Transition, computed, defineComponent, onMounted, onUnmounted, reactive, ref, watch, toRef, ComputedRef, nextTick, defineAsyncComponent } from "vue";
- import styles from "./index.module.less";
- import iconBack from "./image/icon-back.png";
- import listImg from "./image/list.png";
- import iconMode from "./image/mode.png";
- import { headImg } from "./image";
- import { Badge, Circle, Popover, Popup, showConfirmDialog, showToast, NoticeBar } from "vant";
- import Speed from "./speed";
- import { evaluatingData, handleStartEvaluat } from "/src/view/evaluating";
- import Settting from "./settting";
- import state, { IPlatform, handleChangeSection, handleResetPlay, handleRessetState, togglePlay, IPlayState, refreshMusicSvg, EnumMusicRenderType } from "/src/state";
- import { getAudioCurrentTime } from "/src/view/audio-list";
- import { followData, toggleFollow } from "/src/view/follow-practice";
- import { api_back } from "/src/helpers/communication";
- import MusicType from "./music-type";
- import ModeTypeMode from "../component/mode-type-mode";
- import { getQuery } from "/src/utils/queryString";
- import { storeData } from "/src/store";
- import TeacherTop from "../custom-plugins/guide-page/teacher-top";
- import StudentTop from "../custom-plugins/guide-page/student-top";
- import { HANDLE_WORK_ADD } from "../custom-plugins/work-index";
- import { browser } from "/src/utils";
- import store from "store";
- import "../component/the-modal-tip/index.module.less";
- import { metronomeData } from "../../helpers/metronome";
- import { toggleMusicSheet } from "/src/view/plugins/toggleMusicSheet";
- import useDrag from "/src/view/plugins/useDrag/index";
- import Dragbom from "/src/view/plugins/useDrag/dragbom";
- import { getGuidance, setGuidance } from "../custom-plugins/guide-page/api";
- // import ModeView from "./modeView";
- import { smoothAnimationState } from "../view-detail/smoothAnimation";
- import { isMusicList, musicListShow } from "../component/the-music-list";
- import { EvaluatingDriver, FollowDriver, PractiseDriver } from "../custom-plugins/guide-driver";
- import { fingerRef } from "/src/page-instrument/view-detail/index"
- import WorkHomePop from "./workHomePop";
- import { handleLoadBeatMusic } from "/src/view/audio-list"
- const ModeView = defineAsyncComponent(() =>
- import('./modeView')
- )
- /** 头部数据和方法 */
- export const headTopData = reactive({
- /** 模式 */
- modeType: "" as "init" | "show",
- /** 显示返回按钮 */
- showBack: true,
- /** 设置弹窗 */
- settingMode: false,
- /* 节奏律动 */
- rhythmMode: false,
- // 节奏律动方向
- rhythmModeDirection: computed(()=> state.fingeringInfo.direction === "transverse" ? "vertical" : "transverse"),
- /** 切换模式 */
- handleChangeModeType(value: "practise" | "follow" | "evaluating") {
- // 后台设置为不能评测
- if (value === "evaluating" && !state.enableEvaluation) return;
- // 打击乐&节奏练习不支持跟练模式
- if (value === "follow" && state.isPercussion) return;
- // 跟练模式,光标只有音符模式,无节拍模式
- if (value === "follow" && metronomeData.cursorMode === 2) {
- metronomeData.cursorMode = 1;
- }
- if (value === "practise") {
- // 切回当前的时值
- const isModeChange = modeChangeHandleTimes("play", "music")
- // 没有切换的时候 不处理下面的
- if (isModeChange) {
- try {
- metronomeData.metro.calculation(state.times);
- } catch (error) {}
- console.log("重新之后的times", state.times, state.fixtime);
- }
- // state.playIngSpeed = state.speed
- }
- if (value === "evaluating") {
- // 如果延迟检测资源还在加载中,给出提示
- if (!evaluatingData.jsonLoadDone) {
- evaluatingData.jsonLoading = true;
- state.audioDone && showToast("资源加载中,请稍后"); //音频资源加载完之后才提示
- return;
- }
- // 如果是pc端, 评测模式暂不可用
- if (state.platform === IPlatform.PC) {
- showConfirmDialog({
- className: "modalTip",
- title: "温馨提示",
- message: "该功能暂未开放,敬请期待!",
- showCancelButton: false,
- });
- return;
- }
- // 评测模式,只有一行谱模式
- // if (!state.isSingleLine) {
- // state.isSingleLine = true;
- // refreshMusicSvg();
- // }
- /* 当前是唱名的模式 */
- if(state.playSource === "mingSong") {
- const isModeChange = modeChangeHandleTimes("play","mingSong","play","music")
- // 没有切换的时候 不处理下面的
- if (isModeChange) {
- try {
- metronomeData.metro.calculation(state.times);
- } catch (error) {}
- console.log("重新之后的times", state.times, state.fixtime);
- }
- }
- // 关闭节奏律动
- headTopData.rhythmMode = false
- smoothAnimationState.isShow.value = false; // 隐藏旋律线
- state.playIngSpeed = state.originSpeed;
- handleStartEvaluat();
- // 开发模式,把此处打开
- // state.modeType = "evaluating";
- // evaluatingData.rendered = true;
- // evaluatingData.soundEffectMode = true;
- } else if (value === "follow") {
- // 关闭节奏律动
- headTopData.rhythmMode = false
- // 跟练模式,只有一行谱模式
- if (!state.isSingleLine) {
- state.isSingleLine = true;
- refreshMusicSvg();
- }
- smoothAnimationState.isShow.value = false;
- toggleFollow();
- }
- headTopData.modeType = "show";
- },
- // 改变模式之前的状态
- oldPlayType: "play",
- // 记录切换模式前的状态
- oldModeType: "practise" as "practise" | "follow" | "evaluating",
- // 作业未完成弹窗
- workHomeNoDone: false,
- });
- export const headData = reactive({
- speedShow: false,
- musicTypeShow: false,
- });
- let resetBtn: ComputedRef<{
- display: boolean;
- disabled: boolean;
- }>;
- // 点击切换的时候才触发提醒
- let isClickMode = false;
- /**
- * 处理模式切换
- * @param oldPlayType 没改变之前的播放模式
- * @param oldPlaySource 没改变之前的播放类型
- * @param isforceReset 是否强制刷新播放状态 模式times时值改变时候也刷新
- */
- export async function handlerModeChange(oldPlayType: "play" | "sing", oldPlaySource: IPlayState, isforceReset?: boolean) {
- const isModeChange = modeChangeHandleTimes(oldPlayType, oldPlaySource);
- // 没有切换的时候 不处理下面的
- if (isModeChange) {
- try {
- metronomeData.metro.calculation(state.times);
- } catch (error) {}
- console.log("重新之后的times", state.times, state.fixtime);
- }
- if (isModeChange || isforceReset) {
- // 重置播放状态
- handleRessetState();
- // 隐藏重播按钮
- resetBtn && (resetBtn.value.display = false);
- }
- // 节拍器音频加载
- await handleLoadBeatMusic()
- // 当模式改变的时候 放在这里是因为需要等谱面加载完成之后再提示(点击按钮模式切换才提示)
- if (isClickMode) {
- showToast({
- message: state.playType === "play" ? "已切换为演奏场景" : "已切换为演唱场景",
- position: "top",
- className: "selectionToast",
- });
- isClickMode = false;
- }
- }
- // 模式切换之后重新给times赋值
- function modeChangeHandleTimes(oldPlayType: "play" | "sing", oldPlaySource: IPlayState, nowPlayType?:"play" | "sing", nowPlaySource?: IPlayState) {
- const playType = nowPlayType || state.playType;
- const playSource = nowPlaySource || state.playSource;
- const { notBeatFixtime, xmlMp3BeatFixTime, difftime } = state.times[0];
- const { isOpenMetronome, isSingOpenMetronome } = state;
- // 因为演奏加了唱名,所以往跟练模式切换和评测模式切换的时候,刷新谱面的时候需要更新时值,这时候调用handleRessetState 会回到练习模式,这里是
- if(state.modeType === "follow" || state.modeType === "evaluating") {
- return false
- }
- // 当相同时候也不处理
- if(oldPlayType === playType && oldPlaySource === playSource) {
- return false
- }
- // 原声向伴奏和伴奏向原声不处理 范唱向伴唱和伴唱向范唱切不处理
- if((oldPlaySource==="music"&&playSource==="background")||(oldPlaySource==="background"&&playSource==="music")){
- return false
- }
- // 唱名到唱名时候不处理
- if(oldPlaySource === "mingSong" && playSource === "mingSong"){
- return false
- }
- // 原生伴奏向范唱伴唱,范唱伴唱向原生伴奏时候,isSingOpenMetronome和isOpenMetronome相等时候不处理
- if(["music","background"].includes(oldPlaySource)&&["music","background"].includes(playSource)&&isOpenMetronome===isSingOpenMetronome){
- return false
- }
- // 当切为 原生伴奏,或者范唱伴唱 时候
- if(playSource==="music" || playSource ==="background"){
- if(playType === "play"){
- // 有节拍器
- if (isOpenMetronome) {
- state.fixtime = notBeatFixtime + xmlMp3BeatFixTime;
- state.times.map((item) => {
- item.time = item.notBeatTime + xmlMp3BeatFixTime;
- item.endtime = item.notBeatEndTime + xmlMp3BeatFixTime;
- item.fixtime = notBeatFixtime + xmlMp3BeatFixTime;
- });
- return true;
- } else {
- state.fixtime = notBeatFixtime;
- state.times.map((item) => {
- item.time = item.notBeatTime;
- item.endtime = item.notBeatEndTime;
- item.fixtime = notBeatFixtime;
- });
- return true;
- }
- }
- if(playType==="sing"){
- // 有节拍器
- if (isSingOpenMetronome) {
- state.fixtime = notBeatFixtime + xmlMp3BeatFixTime;
- state.times.map((item) => {
- item.time = item.notBeatTime + xmlMp3BeatFixTime;
- item.endtime = item.notBeatEndTime + xmlMp3BeatFixTime;
- item.fixtime = notBeatFixtime + xmlMp3BeatFixTime;
- });
- return true;
- } else {
- state.fixtime = notBeatFixtime;
- state.times.map((item) => {
- item.time = item.notBeatTime;
- item.endtime = item.notBeatEndTime;
- item.fixtime = notBeatFixtime;
- });
- return true;
- }
- }
- }
- // 当切为唱名时候
- if(playSource==="mingSong"){
- // 唱名文件也要加上弱起时间 他们制作曲子加了弱起时间 注意这修改了之后给总控平台的时值也需要改
- state.fixtime = difftime;
- state.times.map((item) => {
- item.time = item.xmlNoteTime + difftime;
- item.endtime = item.xmlNoteEndTime + difftime;
- item.fixtime = difftime;
- });
- return true;
- }
- return false;
- }
- export default defineComponent({
- name: "header-top",
- emits: ["close"],
- setup(props, { emit }) {
- const query = getQuery();
- // 是否显示引导
- const showGuide = ref(false);
- const showStudentGuide = ref(false);
- const showWebGuide = ref(true);
- let displayFingeringCache = 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 (headTopData.modeType !== "show" || state.modeType === "follow") return { display: false, disabled: true };
- if (state.modeType === "follow") return { display: false, disabled: true };
- // 评测模式, 音频播放中 禁用
- if (state.modeType === "evaluating" || state.playState === "play") return { display: true, disabled: true };
- return {
- disabled: false,
- display: true,
- };
- });
- /** 节拍器按钮 */
- const metronomeBtn = computed(() => {
- // 选择模式 不显示
- //if (headTopData.modeType !== "show") return { display: false, disabled: true };
- // 音频播放中 禁用
- if (state.playState === "play") return { display: true, disabled: true };
- return {
- disabled: false,
- display: true,
- };
- });
- /** 指法按钮 */
- const fingeringBtn = computed(() => {
- // 后台设置不显示指法
- if (!state.isShowFingering) return { display: true, disabled: true };
- // 没有指法 选择模式 评测模式 跟练模式 不显示
- //if (headTopData.modeType !== "show" || !state.fingeringInfo.name || ["evaluating", "follow"].includes(state.modeType)) return { display: false, disabled: true };
- if (!state.fingeringInfo.name || ["evaluating", "follow"].includes(state.modeType)) return { display: false, disabled: true };
- // 音频播放中 禁用
- if (state.playState === "play") return { display: true, disabled: true };
- return {
- disabled: false,
- display: true,
- };
- });
- /** 摄像头按钮 */
- const cameraBtn = computed(() => {
- // 选择模式 不显示
- if (headTopData.modeType !== "show" || state.modeType !== "evaluating") return { display: false, disabled: true };
- // 音频播放中 禁用
- if (state.playState === "play") return { display: true, disabled: true };
- return {
- disabled: false,
- display: true,
- };
- });
- /** 选段按钮 */
- const selectBtn = computed(() => {
- // 选择模式 不显示
- //if (headTopData.modeType !== "show" || ["follow"].includes(state.modeType)) return { display: false, disabled: true };
- if (["follow"].includes(state.modeType)) return { display: false, disabled: true };
- // 音频播放中 禁用
- if (state.playState === "play" || query.workRecord) return { display: true, disabled: true };
- return {
- disabled: false,
- display: true,
- };
- });
- /** 原声按钮 */
- const originBtn = computed(() => {
- // 没有音源不显示
- if (state.noMusicSource) return { display: false, disabled: false };
- // 选择模式,跟练模式 不显示
- //if (headTopData.modeType !== "show" || state.modeType === "follow") return { display: false, disabled: false };
- if (state.modeType === "follow") return { display: false, disabled: false };
- // 评测开始 禁用
- if (state.modeType === "evaluating") return { display: false, disabled: true };
- if (!state.isAppPlay) {
- // 播放过程中不能切换
- if (state.playState === "play") {
- return { display: true, disabled: true };
- }
- if (state.playType === "play") {
- let index = 0;
- state.music && index++;
- state.accompany && index++;
- state.mingSong && index++;
- if (index > 1) {
- return { display: true, disabled: false };
- }
- } else {
- // 范唱
- let index = 0;
- state.fanSong && index++;
- state.banSong && index++;
- state.mingSong && index++;
- if (index > 1) {
- return { display: true, disabled: false };
- }
- }
- }
- return {
- disabled: true,
- display: true,
- };
- });
- /** 播放类型按钮 */
- const playTypeBtn = computed(() => {
- // 选择模式,跟练模式,评测模式 不显示
- //if (headTopData.modeType !== "show" || state.modeType === "follow" || state.modeType === "evaluating" || query.workRecord) return { display: false, disabled: false };
- if (state.modeType === "follow" || state.modeType === "evaluating" || query.workRecord) return { display: false, disabled: false };
- if (!state.isAppPlay) {
- let index = 0;
- state.music && index++;
- state.accompany && index++;
- let songIndex = 0;
- state.fanSong && songIndex++;
- state.banSong && songIndex++;
- state.mingSong && songIndex++;
- // 演唱和演奏 都有数据的时间不禁用
- if (songIndex > 0 && index > 0) {
- // 音频播放中 禁用
- if (state.playState === "play") {
- return { display: true, disabled: true };
- }
- return { display: true, disabled: false };
- }
- }
- return {
- disabled: false,
- display: false,
- };
- });
- /** 模式切换按钮 */
- const toggleBtn = computed(() => {
- // 上课页面不显示
- if(state.isAttendClass) return { display: false, disabled: false };
- // 老师端,打击乐&节奏练习不显示
- if (state.isPercussion && state.platform === IPlatform.PC) return { display: false, disabled: false };
- if(state.isCombineRender) return { display: false, disabled: false };
- // 没有音源不显示
- if (state.noMusicSource) return { display: false, disabled: false };
- // 不是演奏模式 影藏
- if (state.playType !== "play") return { display: false, disabled: false };
- // 选择模式, url设置模式 不显示
- if (headTopData.modeType !== "show" || !headTopData.showBack) return { display: false, disabled: false };
- // 跟练开始, 评测开始 播放开始 隐藏
- if (state.playState == "play" || followData.start || evaluatingData.startBegin) return { display: false, disabled: false };
- return {
- display: true,
- disabled: false,
- };
- });
- /** 播放按钮 */
- const playBtn = computed(() => {
- // 没有音源不显示
- if (state.noMusicSource) return { display: false, disabled: false };
- // 选择模式 不显示
- if (headTopData.modeType !== "show") return { display: false, disabled: false };
- // 评测模式 不显示,跟练模式 不显示
- if (["evaluating", "follow"].includes(state.modeType)) return { display: false, disabled: true };
- // midi音频未初始化完成不可点击
- if (state.isAppPlay && state.midiPlayIniting) return { display: true, disabled: true };
- return {
- display: true,
- disabled: false,
- };
- });
- /** 节奏律动 */
- const rhythmBtn = computed(() => {
- if(state.isCombineRender) return { display: false, disabled: false };
- // 跟练和评测显示
- if (["evaluating", "follow"].includes(state.modeType)) return { display: false, disabled: false, playIng: false };
- // 播放过程中不让切换
- if (state.playState == "play") {
- if(headTopData.rhythmMode) {
- return {
- display: true,
- disabled: true,
- playIng: true
- }
- }else{
- return {
- display: true,
- disabled: true,
- playIng: false
- }
- }
- };
- return {
- display: true,
- disabled: false,
- playIng: false
- };
- });
- /** 重播按钮 */
- resetBtn = computed(() => {
- // 没有音源不显示
- if (state.noMusicSource) return { display: false, disabled: false };
- // 选择模式 不显示
- if (headTopData.modeType !== "show") return { display: false, disabled: false };
- // 评测模式 不显示,跟练模式 不显示
- if (["evaluating", "follow"].includes(state.modeType)) return { display: false, disabled: true };
- // 播放状态 不显示
- if (state.playState === "play") return { display: false, disabled: true };
- // 播放进度为0 不显示
- const currentTime = getAudioCurrentTime();
- // midi音频未初始化完成不可点击
- if (state.isAppPlay && state.midiPlayIniting) return { display: false, disabled: true };
- if (!currentTime) return { display: false, disabled: true };
- return {
- display: true,
- disabled: false,
- };
- });
- const isAllBtns = computed(() => {
- const flag = converBtn.value.display && speedBtn.value.display && selectBtn.value.display && originBtn.value.display && toggleBtn.value.display && showGuide.value;
- return flag;
- });
- const isAllBtnsStudent = computed(() => {
- const flag = converBtn.value.display && speedBtn.value.display && selectBtn.value.display && originBtn.value.display && toggleBtn.value.display && showStudentGuide.value;
- return flag;
- });
- const showGuideIndex = computed(() => {
- // 从课堂乐器学生端课件预览默认不显示会员
- if (storeData.user.vipMember || state.paymentType === "FREE" || query.showCourseMember === "true") {
- // 学生端
- return true;
- } else {
- // vip
- return false;
- }
- });
- const browInfo = browser();
- // 返回校验, 如果是作业模式,并且作业没有达标需要给出弹窗提示
- const checkBack = () => {
- if (query.workRecord) {
- console.log('作业是否达标',state.isWorkDone)
- }
- if (query.workRecord && !state.isWorkDone) {
- headTopData.workHomeNoDone = true
- } else {
- handleBack()
- }
- }
- /** 返回 */
- const handleBack = () => {
- HANDLE_WORK_ADD();
- // 不在APP中,
- if (!storeData.isApp) {
- window.parent.postMessage(
- {
- api: "back",
- },
- "*"
- );
- window.close();
- return;
- }
- if ((browInfo.iPhone || browInfo.ios) && query.workRecord) {
- setTimeout(() => {
- api_back();
- }, 550);
- return;
- }
- api_back();
- };
-
- const handleResult = (type: any) => {
- if (type) {
- headTopData.workHomeNoDone = false
- } else {
- headTopData.workHomeNoDone = false
- handleBack()
- }
- }
- /** 根据参数设置模式 */
- const getQueryModelSetModelType = () => {
- /** 作业模式 start, 如果为作业模式不处理,让作业模块处理 */
- if (query.workRecord) {
- return;
- }
- /** 作业模式 end */
- if (state.defaultModeType == 1) {
- headTopData.handleChangeModeType("practise");
- // if (state.platform === IPlatform.PC || state.isPreView) {
- // headTopData.showBack = false;
- // }
- if (state.isPreView) {
- headTopData.showBack = false;
- }
- } else {
- if (query.modelType) {
- if (query.modelType === "practise") {
- headTopData.handleChangeModeType("practise");
- } else if (query.modelType === "evaluating") {
- headTopData.handleChangeModeType("evaluating");
- }
- headTopData.showBack = false;
- } else {
- setTimeout(() => {
- headTopData.modeType = "init";
- }, 500);
- }
- }
- };
- /** 课件播放 */
- const changePlay = (res: any) => {
- // console.log('监听上课页面message',res)
- if (res?.data?.api === "setPlayState") {
- togglePlay("paused", true);
- }
- if(res?.data?.api === 'togglePlayState') {
- // if(state.playState === "play") {
- // togglePlay("paused");
- // }
- // if(state.playState === 'paused') {
- // togglePlay("play");
- // }
- console.log('togglePlayState', state.playState)
- togglePlay(state.playState === "play" ? "paused" : "play");
- }
- // 上课页面,按钮方向
- if (res?.data?.api === "imagePos") {
- if (res?.data.data) {
- state.playBtnDirection = res.data.data === "right" ? "right" : "left";
- // if (state.fingeringInfo.direction === "vertical" && state.setting.displayFingering) {
- // state.musicScoreBtnDirection = state.playBtnDirection === 'right' ? 'left' : 'right';
- // } else {
- // state.musicScoreBtnDirection = state.playBtnDirection;
- // }
- state.musicScoreBtnDirection = state.playBtnDirection;
- }
- }
- };
- const parentClassName = "settingBoxClass_drag";
- const userId = storeData.user?.id ? String(storeData.user?.id) : "";
- const positionInfo =
- state.platform !== IPlatform.PC
- ? {
- styleDrag: { value: null },
- }
- : useDrag([`${parentClassName} .top_draging`, `${parentClassName} .bom_drag`], parentClassName, toRef(headTopData, "settingMode"), userId);
- const speedClassName = "speedBoxClass_drag";
- const speedInfo =
- state.platform !== IPlatform.PC
- ? {
- styleDrag: { value: null },
- }
- : useDrag([`${speedClassName} .top_draging`, `${speedClassName} .bom_drag`], speedClassName, toRef(headData, "speedShow"), userId);
- onMounted(() => {
- getQueryModelSetModelType();
- window.addEventListener("message", changePlay);
- if (state.platform === IPlatform.PC) {
- showGuide.value = true;
- } else {
- showStudentGuide.value = true;
- }
- if (query.showWebGuide === "false") {
- showWebGuide.value = false;
- }
- document.addEventListener("keydown", (e: KeyboardEvent) => {
- if (e.code === "Tab") {
- e.stopPropagation();
- e.preventDefault();
- // onStartPlayState();
- togglePlay(state.playState === "play" ? "paused" : "play");
- }
- });
- });
- onUnmounted(() => {
- window.removeEventListener("message", changePlay);
- });
- const noticeBarWidth = ref<number>();
- watch(
- () => smoothAnimationState.isShow.value,
- () => {
- // NoticeBar能不能滚动
- if ((smoothAnimationState.isShow.value || state.isCombineRender) && isMusicList.value) {
- nextTick(() => {
- const widthCon = (document.querySelector("#noticeBarRollDom .van-notice-bar__content") as any)?.offsetWidth || undefined;
- noticeBarWidth.value = widthCon;
- });
- }
- },
- { immediate: true }
- );
- // 设置改变触发
- watch(state.setting, () => {
- console.log(state.setting, "state.setting");
- store.set("musicscoresetting", state.setting);
- });
- // 获取引导页信息
- const getAllGuidance = async () => {
- let guideInfo: any = null;
- try {
- const res = await getGuidance({ guideTag: "guideInfo" });
- if (res.data) {
- guideInfo = JSON.parse(res.data?.guideValue) || null;
- } else {
- guideInfo = {};
- }
- state.guideInfo = guideInfo;
- } catch (e) {
- console.log(e);
- }
- };
- getAllGuidance();
- // 完成拖动弹窗引导页
- const handleGuide = async () => {
- state.guideInfo.teacherDrag = true;
- try {
- const res = await setGuidance({ guideTag: "guideInfo", guideValue: JSON.stringify(state.guideInfo) });
- } catch (e) {
- console.log(e);
- }
- };
- return () => (
- <>
- <div
- class={[styles.headerTop, styles[state.modeType] ,state.platform === IPlatform.PC && state.musicScoreBtnDirection === "left" ? styles.headerTopRight : ""]}
- onClick={(e: Event) => {
- e.stopPropagation();
- if (state.platform === IPlatform.PC) {
- // 显示隐藏菜单
- window.parent.postMessage(
- {
- api: "onAttendToggleMenu",
- },
- "*"
- );
- }
- }}
- >
- {/* 返回和标题 */}
- {!(state.playState == "play" || followData.start || evaluatingData.startBegin) && (
- <div id="noticeBarRollDom" class={styles.headTopLeftBox}>
- {
- !query.isMove && !state.isAttendClass && <img src={iconBack} class={["headTopBackBtn", styles.img, !headTopData.showBack && styles.hidenBack]} onClick={checkBack} />
- }
- {smoothAnimationState.isShow.value || state.isCombineRender ? (
- <div
- style={
- noticeBarWidth.value
- ? {
- "--noticeBarWidth": noticeBarWidth.value + "px",
- }
- : {}
- }
- class={[styles.title, state.isCbsView && styles.blackTitle, "headeTopTitleBtn"]}
- onClick={() => {
- isMusicList.value && !state.isAttendClass && (musicListShow.value = true);
- }}
- >
- {isMusicList.value && !state.isAttendClass && <div class={[styles.symbolNote, "driver-8"]}></div>}
- <NoticeBar text={state.examSongName} background="none" />
- </div>
- ) : (
- isMusicList.value && !state.isAttendClass && (
- <img
- src={listImg}
- class={[styles.img, styles.listImg, "driver-8"]}
- onClick={() => {
- musicListShow.value = true;
- }}
- />
- )
- )}
- </div>
- )}
- {/* 模式切换 */}
- {
- <div
- id={state.platform === IPlatform.PC ? "teacherTop-0" : "studnetT-0"}
- style={{ display: toggleBtn.value.display ? "" : "none" }}
- class={["driver-9", styles.modeChangeBox, toggleBtn.value.disabled && styles.disabled]}
- onClick={() => {
- headTopData.oldModeType = state.modeType;
- handleRessetState();
- headTopData.modeType = "init";
- }}
- >
- <img class={styles.img} src={iconMode} />
- <div class={styles.title}>{state.modeType === "practise" ? "练习模式" : state.modeType === "follow" ? "跟练模式" : state.modeType === "evaluating" ? "评测模式" : ""}</div>
- </div>
- }
- {/* 模式提醒 */}
- {state.modeType === "practise" && !rhythmBtn.value.playIng && (
- <div class={[styles.modeWarn, "practiseModeWarn", state.platform === IPlatform.PC && state.musicScoreBtnDirection === "left" ? styles.modeWarnRight : ""]}>
- <img src={state.playType === "play" ? headImg("perform1.png") : headImg("sing1.png")} />
- <div>{state.playType === "play" ? "演奏场景" : "演唱场景"}</div>
- </div>
- )}
- {/* 功能按钮 */}
- <div
- class={[styles.headRight]}
- onClick={(e: Event) => {
- e.stopPropagation();
- }}
- >
- {/* 一行谱模式,暂不支持节拍指针 */}
- {/* {!state.isSingleLine ? (
- <div
- class={[styles.btn, state.platform === IPlatform.PC ? styles.pcBtn : ""]}
- onClick={() => {
- // 切换光标模式
- let mode = metronomeData.cursorMode;
- if (["follow"].includes(state.modeType)) {
- mode = metronomeData.cursorMode === 1 ? 3 : 1;
- } else {
- mode = metronomeData.cursorMode === 3 ? 1 : metronomeData.cursorMode + 1;
- }
- metronomeData.cursorMode = mode;
- }}
- >
- <img class={styles.iconBtn} src={headImg(metronomeData.cursorMode === 1 ? "cursor-icon-1.svg" : metronomeData.cursorMode === 2 ? "cursor-icon-2.svg" : metronomeData.cursorMode === 3 ? "cursor-icon-3.svg" : "")} />
- <span class={styles.iconContent}>
- {metronomeData.cursorMode === 1 ? "音符指针" : metronomeData.cursorMode === 2 ? "节拍指针" : metronomeData.cursorMode === 3 ? "关闭指针" : ""}
- {metronomeData.cursorTips && (
- <>
- <i class={styles.arrowIcon}></i>
- <div class={[styles["botton-tips"], metronomeData.cursorMode === 3 ? styles.tipSpec : ""]}>{metronomeData.cursorTips}</div>
- </>
- )}
- </span>
- </div>
- ) : null} */}
- <div
- style={{ display: playTypeBtn.value.display ? "" : "none" }}
- class={["driver-2", styles.btn, playTypeBtn.value.disabled && styles.disabled, styles.playType]}
- onClick={() => {
- const oldPlayType = state.playType;
- headTopData.oldPlayType = oldPlayType;
- const oldPlaySource = state.playSource;
- if (state.playType === "play") {
- state.playType = "sing";
- state.playSource = state.fanSong ? "music" : state.banSong ? "background" : "mingSong";
- } else {
- state.playType = "play";
- state.playSource = state.music ? "music" : state.accompany ? "background" : "mingSong";
- }
- isClickMode = true;
- // 有指法并且显示指法的时候 切换到演唱模式 需要影藏指法
- let isRefresh = false;
- if (state.isShowFingering && state.fingeringInfo.name && (state.setting.displayFingering || displayFingeringCache)) {
- if (state.playType === "sing") {
- state.setting.displayFingering = false;
- displayFingeringCache = true;
- } else {
- state.setting.displayFingering = displayFingeringCache;
- displayFingeringCache = false;
- }
- // 如果是竖屏指法和一行谱的时候 改变指法值的时候state 会调用刷新 refreshMusicSvg 所以下面不调用
- if (state.fingeringInfo.direction === "vertical" && !state.isSingleLine) {
- isRefresh = true;
- }
- }
- // 有歌词的时候,切换播放模式,需要重新渲染谱面 指法不刷新谱面的时候
- if (state.xmlHasLyric && !isRefresh) {
- refreshMusicSvg();
- } else if (!isRefresh) {
- handlerModeChange(oldPlayType, oldPlaySource, true);
- }
- }}
- >
- <img style={{ display: state.playType === "play" ? "" : "none" }} class={styles.iconBtn} src={headImg(`perform.png`)} />
- <img style={{ display: state.playType === "play" ? "none" : "" }} class={styles.iconBtn} src={headImg(`sing.png`)} />
- <span>{state.playType === "play" ? "演奏" : "演唱"}</span>
- </div>
- <div
- id={state.platform === IPlatform.PC ? "teacherTop-1" : "studnetT-1"}
- style={{ display: originBtn.value.display ? "" : "none" }}
- class={["driver-3", styles.btn, originBtn.value.disabled && styles.disabled, state.playType === "play" ? styles.playSource : styles.songSource]}
- onClick={async () => {
- const oldPlayType = state.playType;
- const oldPlaySource = state.playSource;
- if (state.playType === "play") {
- if (state.playSource === "music") {
- state.playSource = state.accompany ? "background" : "mingSong";
- } else if (state.playSource === "background") {
- state.playSource = state.mingSong ? "mingSong" : "music";
- } else {
- state.playSource = state.music ? "music" : "background";
- }
- } else {
- if (state.playSource === "music") {
- state.playSource = state.banSong ? "background" : "mingSong";
- } else if (state.playSource === "background") {
- state.playSource = state.mingSong ? "mingSong" : "music";
- } else {
- state.playSource = state.fanSong ? "music" : "background";
- }
- }
- await handlerModeChange(oldPlayType, oldPlaySource);
- showToast({
- message: state.playType === "play" ? (state.playSource === "music" ? "已切换为原声" : state.playSource === "background" ? "已切换为伴奏" : "已切换为唱名") : state.playSource === "music" ? "已切换为范唱" : state.playSource === "background" ? "已切换为伴唱" : "已切换为唱名",
- position: "top",
- className: "selectionToast",
- });
- }}
- >
- <img style={{ display: state.playSource === "music" ? "" : "none" }} class={styles.iconBtn} src={state.playType === "play" ? headImg(`music.png`) : headImg(`music1.png`)} />
- <img style={{ display: state.playSource === "background" ? "" : "none" }} class={styles.iconBtn} src={state.playType === "play" ? headImg(`background.png`) : headImg(`background1.png`)} />
- <img style={{ display: state.playSource === "mingSong" ? "" : "none" }} class={styles.iconBtn} src={headImg(`mingsong.png`)} />
- <span>{state.playSource === "music" ? (state.playType === "play" ? "原声" : "范唱") : state.playSource === "background" ? (state.playType === "play" ? "伴奏" : "伴唱") : "唱名"}</span>
- </div>
- <div
- style={{ display: rhythmBtn.value.display ? "" : "none" }}
- class={["driver-777", styles.btn, styles.rhythmMode, headTopData.rhythmMode && styles.isrhythmMode, rhythmBtn.value.disabled && styles.disabled]}
- onClick={() => {
- headTopData.rhythmMode = !headTopData.rhythmMode
- }}
- >
- <img class={styles.iconBtn} src={headImg(`rhythm.png`)} />
- <span>律动</span>
- </div>
- <div
- id={state.platform === IPlatform.PC ? "teacherTop-2" : "studnetT-2"}
- style={{ display: selectBtn.value.display ? "" : "none" }}
- class={["driver-4", styles.btn, selectBtn.value.disabled && styles.disabled, styles.section, state.sectionStatus && styles.isSection]}
- onClick={() => handleChangeSection()}
- >
- <img style={{ display: state.section.length === 0 ? "" : "none" }} class={styles.iconBtn} src={headImg(`section0.png`)} />
- <img style={{ display: state.section.length === 1 ? "" : "none" }} class={styles.iconBtn} src={headImg(`section1.png`)} />
- <img style={{ display: state.section.length === 2 ? "" : "none" }} class={styles.iconBtn} src={headImg(`section2.png`)} />
- <span>选段</span>
- </div>
- {
- <>
- <div
- style={{ display: metronomeBtn.value.display ? "" : "none" }}
- class={["driver-5", styles.btn, styles.metronomeBtn, metronomeBtn.value.disabled && styles.disabled, headData.speedShow && styles.isSpeed, styles.speed]}
- onClick={async () => {
- headData.speedShow = !headData.speedShow;
- }}
- >
- <img style={{ display: metronomeData.disable ? "block" : "none" }} class={styles.iconBtn} src={headImg("tickon.png")} />
- <img style={{ display: !metronomeData.disable ? "block" : "none" }} class={styles.iconBtn} src={headImg("tickoff.png")} />
- <span style={{ whiteSpace: "nowrap" }}>节拍</span>
- <div class={styles.speedCon}>
- <img src={headImg(`${state.speedIcon}.png`)} />
- <div>{Math.floor(state.speed)}</div>
- </div>
- </div>
- {
- <Popup v-model:show={headData.speedShow} class="popup-custom van-scale center-closeBtn speedBoxClass_drag" transition="van-scale" teleport="body" style={speedInfo.styleDrag.value} overlay-style={{ background: "rgba(0, 0, 0, 0.7)" }}>
- <Speed />
- {state.platform === IPlatform.PC && <Dragbom showGuide={!state.guideInfo?.teacherDrag} onGuideDone={handleGuide} />}
- </Popup>
- }
- </>
- }
- {/* {state.enableNotation ? (
- <Popover trigger="manual" v-model:show={headData.musicTypeShow} class={state.platform === IPlatform.PC && styles.pcTransPop} placement={state.platform === IPlatform.PC ? "top-end" : "bottom-end"} overlay={false} offset={state.platform === IPlatform.PC ? [0, 40] : [0, 8]}>
- {{
- reference: () => (
- <div
- id={state.platform === IPlatform.PC ? "teacherTop-5" : "studnetT-5"}
- 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={headImg("icon_zhuanpu.svg")} />
- <span>{state.musicRenderType === "staff" ? "转简谱" : "转五线谱"}</span>
- </div>
- ),
- default: () => <MusicType />,
- }}
- </Popover>
- ) : null} */}
- {state.musicRendered && !query.lessonTrainingId && !query.questionId && state.isConcert && (
- <div
- class={[styles.btn, state.playState === "play" && fingeringBtn.value.disabled && styles.disabled, toggleMusicSheet.show && styles.isMusicSheet, styles.musicSheet, "driver-10"]}
- onClick={() => {
- toggleMusicSheet.toggle(true);
- }}
- >
- <img class={styles.iconBtn} src={headImg(`shenggui.png`)} />
- <span>声部</span>
- </div>
- )}
- <div
- id={state.platform === IPlatform.PC ? "teacherTop-6" : "studnetT-6"}
- style={{ display: settingBtn.value.display ? "" : "none" }}
- class={["driver-6", styles.btn, settingBtn.value.disabled && styles.disabled, headTopData.settingMode && styles.isSettingMode, styles.settingMode]}
- onClick={() => (headTopData.settingMode = true)}
- >
- <img class={styles.iconBtn} src={headImg("icon_menu.png")} />
- <span>设置</span>
- </div>
- </div>
- </div>
- {/** 指法点击区域 */}
- {
- state.fingeringInfo.direction === "transverse" && state.setting.displayFingering ?
- <div class={styles.headerMid} onClick={() => {
- fingerRef.value?.doubeClick()
- }}></div> : null
- }
- {/* 播放按钮 */}
- <div
- id="studnetT-7"
- style={{
- display: playBtn.value.display ? "" : "none" ,
- opacity: rhythmBtn.value.playIng? "0.4" : "1"
- }}
- class={[
- // 引导使用的类
- "driver-1",
- styles.playBtn,
- playBtn.value.disabled && styles.disabled,
- state.platform === IPlatform.PC && state.musicScoreBtnDirection === "left" ? styles.playLeftButton : state.platform === IPlatform.PC && state.musicScoreBtnDirection === "right" ? styles.playRightButton : "",
- ]}
- onClick={() => {
- // C调能播放唱名,非C调时,只有谱面类型是首调时,才能播放唱名
- if (!state.isCTone && state.playSource === 'mingSong') {
- const notPlayDesc = state.musicRenderType === EnumMusicRenderType.staff ? '该曲目的五线谱目前还不支持播放唱名' : state.musicRenderType === EnumMusicRenderType.fixedTone ? '该曲目的固定调目前还不支持播放唱名' : '';
- if (notPlayDesc) {
- showToast({
- message: notPlayDesc,
- position: "top",
- className: "selectionToast",
- });
- return
- }
- }
- togglePlay(state.playState === "play" ? "paused" : "play")
- }}
- >
- <div class={styles.btnWrap}>
- <img style={{ display: state.playState === "play" ? "none" : "" }} class={styles.iconBtn} src={headImg("icon_play.png")} />
- <img style={{ display: state.playState === "play" ? "" : "none" }} class={styles.iconBtn} src={headImg("icon_pause.png")} />
- <Circle style={{ opacity: state.playState === "play" ? 1 : 0 }} class={styles.progress} stroke-width={60} stroke-linecap={"square"} currentRate={state.playProgress} rate={100} color="#FFE36A" layer-color="rgba(255,255,255,0.5)" />
- </div>
- </div>
- {/* 重播按钮 */}
- <div
- id="tips-step-9"
- style={{ display: resetBtn.value.display ? "" : "none" }}
- class={[styles.resetBtn, resetBtn.value.disabled && styles.disabled, state.platform === IPlatform.PC && state.musicScoreBtnDirection === "left" ? styles.pauseLeftButton : state.platform === IPlatform.PC && state.musicScoreBtnDirection === "right" ? styles.pauseRightButton : ""]}
- onClick={() => handleResetPlay()}
- >
- <img class={styles.iconBtn} src={headImg("icon_reset.png")} />
- </div>
- <Popup v-model:show={headTopData.settingMode} class="popup-custom van-scale center-closeBtn settingBoxClass_drag" transition="van-scale" teleport="body" style={positionInfo.styleDrag.value} overlay-style={{ background: "rgba(0, 0, 0, 0.7)" }}>
- <Settting />
- {state.platform === IPlatform.PC && <Dragbom showGuide={!state.guideInfo?.teacherDrag} onGuideDone={handleGuide} />}
- </Popup>
- {/* 模式切换 */}
- {/* <ModeTypeMode /> */}
- <ModeView></ModeView>
- {/* isAllBtns */}
- {/* {isAllBtns.value && !query.isCbs && showGuideIndex.value && <TeacherTop></TeacherTop>}
- {isAllBtnsStudent.value && !query.isCbs && showGuideIndex.value && <StudentTop></StudentTop>} */}
- {/* 练习模式功能引导 加载音频完成 不是会员 */}
- {state.modeType === "practise" && headTopData.modeType !== "init" && !query.isCbs && state.audioDone && !state.isLoading && !state.isVip && showWebGuide.value && (
- <PractiseDriver
- statusAll={{
- playBtnStatus: playBtn.value.display,
- subjectStatus: state.musicRendered && !query.lessonTrainingId && !query.questionId && state.isConcert,
- modelTypeStatus: toggleBtn.value.display,
- playType: playTypeBtn.value.display,
- originPlayType: state.playType === "play" ? true : false,
- originBtnStatus: originBtn.value.display,
- backTitle: !(state.playState == "play" || followData.start || evaluatingData.startBegin) && isMusicList.value,
- titleType: smoothAnimationState.isShow.value ? "TEXT" : isMusicList.value ? "IMG" : "NONE",
- }}
- />
- )}
- {/* 跟练模式功能引导 加载音频完成 不是会员 */}
- {state.modeType === "follow" && headTopData.modeType !== "init" && !query.isCbs && state.audioDone && !state.isLoading && !state.isVip && showWebGuide.value && (
- <FollowDriver
- statusAll={{
- subjectStatus: state.musicRendered && !query.lessonTrainingId && !query.questionId && state.isConcert,
- }}
- />
- )}
- {/* 评测模式功能引导 加载音频完成 不是会员 */}
- {state.modeType === "evaluating" && headTopData.modeType !== "init" && !evaluatingData.earphoneMode && !query.isCbs && state.audioDone && !state.isLoading && !state.isVip && evaluatingData.websocketState && !evaluatingData.startBegin && evaluatingData.checkEnd && showWebGuide.value && (
- <EvaluatingDriver
- statusAll={{
- subjectStatus: state.musicRendered && !query.lessonTrainingId && !query.questionId && state.isConcert,
- }}
- />
- )}
- {/** 评测作业,没有完成时,提示弹窗 */}
- <Popup v-model:show={headTopData.workHomeNoDone} class="popup-custom van-scale center-closeBtn" transition="van-scale" teleport="body" style={positionInfo.styleDrag.value} overlay-style={{ background: "rgba(0, 0, 0, 0.7)" }}>
- <WorkHomePop onClose={handleResult} />
- </Popup>
- </>
- );
- },
- });
|