|
@@ -26,23 +26,23 @@ import TheMusicList from "../component/the-music-list";
|
|
import { storeData } from "/src/store";
|
|
import { storeData } from "/src/store";
|
|
import ViewFigner from "../view-figner";
|
|
import ViewFigner from "../view-figner";
|
|
import { recalculateNoteData } from "/src/view/selection";
|
|
import { recalculateNoteData } from "/src/view/selection";
|
|
-import ToggleMusicSheet from "/src/view/plugins/toggleMusicSheet"
|
|
|
|
|
|
+import ToggleMusicSheet from "/src/view/plugins/toggleMusicSheet";
|
|
|
|
|
|
/**
|
|
/**
|
|
* 特殊教材分类id
|
|
* 特殊教材分类id
|
|
*/
|
|
*/
|
|
-export const classids = [1, 2, 6, 7, 8, 9, 3, 10, 11, 12, 13, 4, 14, 15, 16, 17, 30, 31, 35, 36, 46, 108]; // 大雅金唐, 竖笛教程, 声部训练展开的分类ID
|
|
|
|
|
|
+export const classids = [1, 2, 6, 7, 8, 9, 3, 10, 11, 12, 13, 4, 14, 15, 16, 17, 30, 31, 35, 36, 46, 108]; // 大雅金唐, 竖笛教程, 声部训练展开的分类ID
|
|
|
|
|
|
const calcCeilFrequency = (frequency: number) => {
|
|
const calcCeilFrequency = (frequency: number) => {
|
|
- if (frequency) return frequency * 1000 * 2 / 1000;
|
|
|
|
- return 0
|
|
|
|
|
|
+ if (frequency) return (frequency * 1000 * 2) / 1000;
|
|
|
|
+ return 0;
|
|
};
|
|
};
|
|
/** 需要处理频率的乐器
|
|
/** 需要处理频率的乐器
|
|
*/
|
|
*/
|
|
const resetFrequency = (list: any[]) => {
|
|
const resetFrequency = (list: any[]) => {
|
|
const instrumentNames = ["ocarina", "pan-flute", "piccolo", "hulusi-flute"];
|
|
const instrumentNames = ["ocarina", "pan-flute", "piccolo", "hulusi-flute"];
|
|
if (!state.fingeringInfo?.name || !instrumentNames.includes(state.fingeringInfo.name)) return list;
|
|
if (!state.fingeringInfo?.name || !instrumentNames.includes(state.fingeringInfo.name)) return list;
|
|
- console.log(state.subjectId, state.fingeringInfo.name, instrumentNames)
|
|
|
|
|
|
+ console.log(state.subjectId, state.fingeringInfo.name, instrumentNames);
|
|
for (let i = 0; i < list.length; i++) {
|
|
for (let i = 0; i < list.length; i++) {
|
|
if (list[i].prevFrequency) list[i].prevFrequency = calcCeilFrequency(list[i].prevFrequency);
|
|
if (list[i].prevFrequency) list[i].prevFrequency = calcCeilFrequency(list[i].prevFrequency);
|
|
if (list[i].frequency) list[i].frequency = calcCeilFrequency(list[i].frequency);
|
|
if (list[i].frequency) list[i].frequency = calcCeilFrequency(list[i].frequency);
|
|
@@ -55,7 +55,7 @@ const resetFrequency = (list: any[]) => {
|
|
* 乐器指法处理
|
|
* 乐器指法处理
|
|
*/
|
|
*/
|
|
const setNoteHalfTone = (list: any[]) => {
|
|
const setNoteHalfTone = (list: any[]) => {
|
|
- const instrumentNames = ["hulusi-flute"] // ["ocarina", "pan-flute", "piccolo"];
|
|
|
|
|
|
+ const instrumentNames = ["hulusi-flute"]; // ["ocarina", "pan-flute", "piccolo"];
|
|
if (!state.fingeringInfo?.name || !instrumentNames.includes(state.fingeringInfo.name)) return list;
|
|
if (!state.fingeringInfo?.name || !instrumentNames.includes(state.fingeringInfo.name)) return list;
|
|
for (let i = 0; i < list.length; i++) {
|
|
for (let i = 0; i < list.length; i++) {
|
|
const note = list[i];
|
|
const note = list[i];
|
|
@@ -76,6 +76,7 @@ export default defineComponent({
|
|
paddingLeft: "",
|
|
paddingLeft: "",
|
|
headerHide: false,
|
|
headerHide: false,
|
|
fingerPreView: false,
|
|
fingerPreView: false,
|
|
|
|
+ fingerPreViewAnimation: false,
|
|
orientation: 0,
|
|
orientation: 0,
|
|
fingerPreViewGuide: false,
|
|
fingerPreViewGuide: false,
|
|
});
|
|
});
|
|
@@ -90,7 +91,7 @@ export default defineComponent({
|
|
}
|
|
}
|
|
};
|
|
};
|
|
onBeforeMount(() => {
|
|
onBeforeMount(() => {
|
|
- console.time('渲染加载耗时')
|
|
|
|
|
|
+ console.time("渲染加载耗时");
|
|
api_keepScreenLongLight();
|
|
api_keepScreenLongLight();
|
|
getAPPData();
|
|
getAPPData();
|
|
api_setStatusBarVisibility();
|
|
api_setStatusBarVisibility();
|
|
@@ -125,43 +126,41 @@ export default defineComponent({
|
|
detailData.isLoading = false;
|
|
detailData.isLoading = false;
|
|
};
|
|
};
|
|
|
|
|
|
- const setState = (data: any, index: number) => {
|
|
|
|
- state.appName = "COLEXIU";
|
|
|
|
- state.detailId = data.id;
|
|
|
|
- state.xmlUrl = data.xmlFileUrl;
|
|
|
|
- state.partIndex = index;
|
|
|
|
- state.trackId = data.track;
|
|
|
|
|
|
+ const setState = (data: any, index: number) => {
|
|
|
|
+ state.appName = "COLEXIU";
|
|
|
|
+ state.detailId = data.id;
|
|
|
|
+ state.xmlUrl = data.xmlFileUrl;
|
|
|
|
+ state.partIndex = index;
|
|
|
|
+ state.trackId = data.track;
|
|
state.subjectId = data.musicSubject;
|
|
state.subjectId = data.musicSubject;
|
|
- state.categoriesId = data.categoriesId;
|
|
|
|
- state.categoriesName = data.musicTagNames;
|
|
|
|
- state.enableEvaluation = data.canEvaluate ? true : false;
|
|
|
|
- state.examSongId = data.id + "";
|
|
|
|
- state.examSongName = data.musicSheetName;
|
|
|
|
- state.coverImg = data.titleImg ?? "";
|
|
|
|
- // 解析扩展字段
|
|
|
|
- if (data.extConfigJson) {
|
|
|
|
- try {
|
|
|
|
- state.extConfigJson = JSON.parse(data.extConfigJson as string);
|
|
|
|
- } catch (error) {
|
|
|
|
- console.error("解析扩展字段错误:", error);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- state.isOpenMetronome = data.mp3Type === "MP3_METRONOME" ? true : false;
|
|
|
|
- // 曲子包含节拍器,就不开启节拍器
|
|
|
|
- state.needTick = data.mp3Type === "MP3_METRONOME" ? false : true;
|
|
|
|
- state.isShowFingering = data.showFingering ? true : false;
|
|
|
|
- state.music = data.music;
|
|
|
|
- state.accompany = data.accompany;
|
|
|
|
- state.midiUrl = data.midiUrl;
|
|
|
|
- state.parentCategoriesId = data.musicTag;
|
|
|
|
- state.musicSheetCategoriesId = data.musicSheetCategoriesId;
|
|
|
|
- state.playMode = data.audioType === "MP3" ? "MP3" : "MIDI";
|
|
|
|
- state.originSpeed = state.speed = data.playSpeed;
|
|
|
|
- const track = data.code || data.track;
|
|
|
|
- state.track = track ? track.replace(/ /g, "").toLocaleLowerCase() : "";
|
|
|
|
- state.enableNotation = data.notation ? true : false;
|
|
|
|
- // 是否是合奏,先根据background判断
|
|
|
|
- state.isConcert = data.background?.length > 1
|
|
|
|
|
|
+ state.categoriesId = data.categoriesId;
|
|
|
|
+ state.categoriesName = data.musicTagNames;
|
|
|
|
+ state.enableEvaluation = data.canEvaluate ? true : false;
|
|
|
|
+ state.examSongId = data.id + "";
|
|
|
|
+ state.examSongName = data.musicSheetName;
|
|
|
|
+ state.coverImg = data.titleImg ?? "";
|
|
|
|
+ // 解析扩展字段
|
|
|
|
+ if (data.extConfigJson) {
|
|
|
|
+ try {
|
|
|
|
+ state.extConfigJson = JSON.parse(data.extConfigJson as string);
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.error("解析扩展字段错误:", error);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ state.isOpenMetronome = data.mp3Type === "MP3_METRONOME" ? true : false;
|
|
|
|
+ // 曲子包含节拍器,就不开启节拍器
|
|
|
|
+ state.needTick = data.mp3Type === "MP3_METRONOME" ? false : true;
|
|
|
|
+ state.isShowFingering = data.showFingering ? true : false;
|
|
|
|
+ state.music = data.music;
|
|
|
|
+ state.accompany = data.accompany;
|
|
|
|
+ state.midiUrl = data.midiUrl;
|
|
|
|
+ state.parentCategoriesId = data.musicTag;
|
|
|
|
+ state.musicSheetCategoriesId = data.musicSheetCategoriesId;
|
|
|
|
+ state.playMode = data.audioType === "MP3" ? "MP3" : "MIDI";
|
|
|
|
+ state.originSpeed = state.speed = data.playSpeed;
|
|
|
|
+ const track = data.code || data.track;
|
|
|
|
+ state.track = track ? track.replace(/ /g, "").toLocaleLowerCase() : "";
|
|
|
|
+ state.enableNotation = data.notation ? true : false;
|
|
|
|
|
|
// console.log("🚀 ~ state.subjectId:", state.subjectId, state.track as any , state.subjectId)
|
|
// console.log("🚀 ~ state.subjectId:", state.subjectId, state.track as any , state.subjectId)
|
|
// 是否打击乐
|
|
// 是否打击乐
|
|
@@ -172,7 +171,7 @@ export default defineComponent({
|
|
// isRhythmicExercises();
|
|
// isRhythmicExercises();
|
|
state.isPercussion = isRhythmicExercises();
|
|
state.isPercussion = isRhythmicExercises();
|
|
// 设置是否特殊曲谱, 是特殊曲谱取反(不理解之前的思考逻辑), 使用后台设置的速度
|
|
// 设置是否特殊曲谱, 是特殊曲谱取反(不理解之前的思考逻辑), 使用后台设置的速度
|
|
- state.isSpecialBookCategory = !classids.includes(data.musicSheetCategoriesId)
|
|
|
|
|
|
+ state.isSpecialBookCategory = !classids.includes(data.musicSheetCategoriesId);
|
|
|
|
|
|
// 设置指法
|
|
// 设置指法
|
|
const code = state.isConcert ? mappingVoicePart(state.trackId, "ENSEMBLE") : mappingVoicePart(state.subjectId, "INSTRUMENT");
|
|
const code = state.isConcert ? mappingVoicePart(state.trackId, "ENSEMBLE") : mappingVoicePart(state.subjectId, "INSTRUMENT");
|
|
@@ -192,7 +191,9 @@ export default defineComponent({
|
|
|
|
|
|
//课堂乐器, 渲染类型: 五线谱, 简谱
|
|
//课堂乐器, 渲染类型: 五线谱, 简谱
|
|
state.musicRenderType = query.musicRenderType || EnumMusicRenderType.firstTone;
|
|
state.musicRenderType = query.musicRenderType || EnumMusicRenderType.firstTone;
|
|
- console.log('state对象', state)
|
|
|
|
|
|
+ // 是否是合奏,先根据background判断
|
|
|
|
+ state.isConcert = data.background?.length > 1;
|
|
|
|
+ console.log("state对象", state);
|
|
};
|
|
};
|
|
|
|
|
|
const setCustom = () => {
|
|
const setCustom = () => {
|
|
@@ -245,7 +246,7 @@ export default defineComponent({
|
|
resetPlaybackToStart();
|
|
resetPlaybackToStart();
|
|
|
|
|
|
pushAppMusic();
|
|
pushAppMusic();
|
|
- console.timeEnd('渲染加载耗时')
|
|
|
|
|
|
+ console.timeEnd("渲染加载耗时");
|
|
};
|
|
};
|
|
/** 指法配置 */
|
|
/** 指法配置 */
|
|
const fingerConfig = computed<any>(() => {
|
|
const fingerConfig = computed<any>(() => {
|
|
@@ -375,11 +376,7 @@ export default defineComponent({
|
|
class={[styles.detail, state.setting.eyeProtection && "eyeProtection", state.platform === IPlatform.PC && styles.PC]}
|
|
class={[styles.detail, state.setting.eyeProtection && "eyeProtection", state.platform === IPlatform.PC && styles.PC]}
|
|
style={{
|
|
style={{
|
|
paddingLeft: detailData.paddingLeft,
|
|
paddingLeft: detailData.paddingLeft,
|
|
- background: state.setting.camera
|
|
|
|
- ? `rgba(${state.setting.eyeProtection ? '253,244,229' : '255,255,255'} ,${
|
|
|
|
- state.setting.cameraOpacity / 100
|
|
|
|
- }) !important`
|
|
|
|
- : '',
|
|
|
|
|
|
+ background: state.setting.camera ? `rgba(${state.setting.eyeProtection ? "253,244,229" : "255,255,255"} ,${state.setting.cameraOpacity / 100}) !important` : "",
|
|
}}
|
|
}}
|
|
>
|
|
>
|
|
<Transition name="van-fade">
|
|
<Transition name="van-fade">
|
|
@@ -392,9 +389,7 @@ export default defineComponent({
|
|
<div class={[styles.headHeight, detailData.headerHide && styles.headHide]}>{state.musicRendered && <HeaderTop />}</div>
|
|
<div class={[styles.headHeight, detailData.headerHide && styles.headHide]}>{state.musicRendered && <HeaderTop />}</div>
|
|
<div
|
|
<div
|
|
id="scrollContainer"
|
|
id="scrollContainer"
|
|
- style={{ ...fingerConfig.value.container,
|
|
|
|
- height: detailData.headerHide ? "100vh" : "",
|
|
|
|
- }}
|
|
|
|
|
|
+ style={{ ...fingerConfig.value.container, height: detailData.headerHide ? "100vh" : "" }}
|
|
class={[styles.container, !state.setting.displayCursor && "hideCursor", browsInfo.xiaomi && styles.xiaomi]}
|
|
class={[styles.container, !state.setting.displayCursor && "hideCursor", browsInfo.xiaomi && styles.xiaomi]}
|
|
onClick={(e: Event) => {
|
|
onClick={(e: Event) => {
|
|
e.stopPropagation();
|
|
e.stopPropagation();
|
|
@@ -409,15 +404,11 @@ export default defineComponent({
|
|
{/* 指法 */}
|
|
{/* 指法 */}
|
|
{state.setting.displayFingering && state.fingeringInfo?.name && (
|
|
{state.setting.displayFingering && state.fingeringInfo?.name && (
|
|
<div style={{ ...fingerConfig.value.fingerBox }}>
|
|
<div style={{ ...fingerConfig.value.fingerBox }}>
|
|
- <Fingering
|
|
|
|
- style={{
|
|
|
|
- background: state.setting.camera
|
|
|
|
- ? `rgba(${state.setting.eyeProtection ? '253,244,229' : '255,255,255'} ,${
|
|
|
|
- state.setting.cameraOpacity / 100
|
|
|
|
- })`
|
|
|
|
- : '',
|
|
|
|
- }}
|
|
|
|
- onOpen={() => handleOpenFignerView()}
|
|
|
|
|
|
+ <Fingering
|
|
|
|
+ style={{
|
|
|
|
+ background: state.setting.camera ? `rgba(${state.setting.eyeProtection ? "253,244,229" : "255,255,255"} ,${state.setting.cameraOpacity / 100})` : "",
|
|
|
|
+ }}
|
|
|
|
+ onOpen={() => handleOpenFignerView()}
|
|
/>
|
|
/>
|
|
</div>
|
|
</div>
|
|
)}
|
|
)}
|
|
@@ -446,9 +437,7 @@ export default defineComponent({
|
|
)}
|
|
)}
|
|
|
|
|
|
{/* 切换曲谱 */}
|
|
{/* 切换曲谱 */}
|
|
- {!query.lessonTrainingId && !query.questionId && state.isConcert && (
|
|
|
|
- <ToggleMusicSheet />
|
|
|
|
- )}
|
|
|
|
|
|
+ {!query.lessonTrainingId && !query.questionId && state.isConcert && <ToggleMusicSheet />}
|
|
|
|
|
|
{state.musicRendered && (
|
|
{state.musicRendered && (
|
|
<>
|
|
<>
|
|
@@ -461,23 +450,24 @@ export default defineComponent({
|
|
</>
|
|
</>
|
|
)}
|
|
)}
|
|
|
|
|
|
- <Popup
|
|
|
|
- zIndex={5050}
|
|
|
|
- teleport="body"
|
|
|
|
- v-model:show={detailData.fingerPreView}
|
|
|
|
- position="bottom"
|
|
|
|
- onOpened={() => {
|
|
|
|
- detailData.fingerPreViewGuide = true;
|
|
|
|
- }}
|
|
|
|
- >
|
|
|
|
- <ViewFigner
|
|
|
|
- show={detailData.fingerPreViewGuide}
|
|
|
|
- subject={state.fingeringInfo.name}
|
|
|
|
- isComponent={true}
|
|
|
|
- onClose={handleCloseFignerView}
|
|
|
|
- />
|
|
|
|
- </Popup>
|
|
|
|
- </div>
|
|
|
|
- );
|
|
|
|
- },
|
|
|
|
|
|
+ <Popup
|
|
|
|
+ zIndex={5050}
|
|
|
|
+ teleport="body"
|
|
|
|
+ v-model:show={detailData.fingerPreView}
|
|
|
|
+ position="bottom"
|
|
|
|
+ onClosed={() => {
|
|
|
|
+ detailData.fingerPreViewAnimation = false;
|
|
|
|
+ }}
|
|
|
|
+ onOpen={() => {
|
|
|
|
+ detailData.fingerPreViewAnimation = true;
|
|
|
|
+ }}
|
|
|
|
+ onOpened={() => {
|
|
|
|
+ detailData.fingerPreViewGuide = true;
|
|
|
|
+ }}
|
|
|
|
+ >
|
|
|
|
+ {detailData.fingerPreViewAnimation && <ViewFigner show={detailData.fingerPreViewGuide} subject={state.fingeringInfo.name} isComponent={true} onClose={handleCloseFignerView} />}
|
|
|
|
+ </Popup>
|
|
|
|
+ </div>
|
|
|
|
+ );
|
|
|
|
+ },
|
|
});
|
|
});
|