123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226 |
- import { PropType, computed, defineComponent, nextTick, onBeforeMount, onMounted, onUnmounted, reactive, ref, toRef } from "vue";
- import styles from "./index.module.less";
- import icons from "./image/icons.json";
- import { FIGNER_INSTRUMENT_DATA, FIGNER_INSTRUMENT_REALKEY, IFIGNER_INSTRUMENT_Note } from "/src/view/figner-preview";
- import { ITypeFingering, IVocals, getFingeringConfig, mappingVoicePart, subjectFingering } from "/src/view/fingering/fingering-config";
- import { Howl } from "howler";
- import { storeData } from "/src/store";
- import { api_back, api_cloudLoading, api_setRequestedOrientation, api_setStatusBarVisibility, isSpecialShapedScreen } from "/src/helpers/communication";
- import Hammer from "hammerjs";
- import { Button, Icon, Loading, Popover, Popup, Progress, Space, showToast } from "vant";
- import GuideIndex from "./guide/guide-index";
- import { getQuery } from "/src/utils/queryString";
- import { browser } from "/src/utils";
- import { usePageVisibility } from "@vant/use";
- import { watch } from "vue";
- import icon_loading_img from "./image/icon_loading_img.png";
- import noteImg from "./image/noteImg.png";
- import state, { IPlatform } from "/src/state";
- import { api_musicalInstrumentList, api_subjectList, getSubjectList } from "../api";
- import ChangeSubject from "./change-subject";
- import { Tabs, Tab } from "vant";
- import useDrag from "/src/hooks/useDrag";
- import Dragbom from "/src/hooks/useDrag/dragbom";
- import useDragGuidance from "/src/hooks/useDrag/useDragGuidance";
- import { FINER_INSTRUMENT_POINT } from "./fingeringPoint";
- export default defineComponent({
- name: "viewFigner",
- emits: ["close"],
- props: {
- show: {
- type: Boolean,
- default: true,
- },
- isComponent: {
- type: Boolean,
- default: false,
- },
- subject: {
- type: String as PropType<IVocals>,
- default: "",
- },
- },
- setup(props, { emit }) {
- const query = getQuery();
- const browsInfo = browser();
- const tempCode = query.code ? query.code.split(",")[0] : "";
- const code = mappingVoicePart(tempCode, "INSTRUMENT");
- const subject = props.isComponent ? props.subject || "pan-flute" : code || "pan-flute";
- const data = reactive({
- linkSource: query.linkSource, // 来源,目前只有课件里使用
- loading: true,
- subject: subject as any,
- realKey: 0,
- notes: [] as IFIGNER_INSTRUMENT_Note[],
- notePoints: [] as any, // 显示的点
- tones: [] as IFIGNER_INSTRUMENT_Note[],
- activeTone: {} as IFIGNER_INSTRUMENT_Note,
- popupActiveTone: {} as IFIGNER_INSTRUMENT_Note,
- activeToneName: "",
- soundFonts: {} as any,
- viewIndex: 0,
- viewTotal: 1,
- noteAudio: null as unknown as Howl,
- transform: {
- scale: 1,
- x: 0,
- y: 0,
- startScale: 1,
- startX: 0,
- startY: 0,
- transition: "",
- },
- tipShow: false,
- tips: [] as IFIGNER_INSTRUMENT_Note[],
- tnoteShow: false,
- loadingSoundFonts: true,
- loadingSoundProgress: 0,
- changeSubjectShow: false,
- huaweiPad: navigator?.userAgent?.includes("UAWEIVRD-W09") ? true : false,
- paddingTop: "",
- paddingLeft: "",
- subjects: [] as any,
- fingeringModeList: [
- {
- text: "指法模式",
- value: "fingeringMode",
- icon: icons.icon_click,
- },
- {
- text: "听音模式",
- value: "listenMode",
- icon: icons.icon_listen,
- },
- {
- text: "音阶模式",
- value: "scaleMode",
- icon: icons.icon_mode,
- },
- ],
- fingeringMode: query.type || ("scaleMode" as "fingeringMode" | "listenMode" | "scaleMode"), // 模式
- noteType: "all" as "#c" | "all", // 音调
- loadingDom: false, // 切换乐器时需要重置
- loadingImg: false, // 切换模式,加载图片
- domOverlapping: false, // 元素是否被遮住
- domOverImgPropery: {
- width: "100%",
- height: "100%",
- } as any,
- });
- const fingerData = reactive({
- relationshipIndex: 0,
- subject: null as unknown as ITypeFingering,
- fingeringInfo: subjectFingering(data.subject),
- });
- if (!props.isComponent) {
- state.fingeringInfo = fingerData.fingeringInfo;
- }
- const getAPPData = async (type: "top" | "left") => {
- const screenData = await isSpecialShapedScreen();
- if (screenData?.content) {
- console.log("🚀 ~ screenData:", screenData.content);
- const { isSpecialShapedScreen, notchHeight } = screenData.content;
- if (isSpecialShapedScreen) {
- if (type === "top") {
- data.paddingTop = 25 + "px";
- }
- if (type === "left") {
- data.paddingLeft = 25 + "px";
- }
- }
- }
- };
- const getHeadTop = () => {
- if (fingerData.fingeringInfo.orientation === 1) {
- getAPPData("top");
- }
- if (fingerData.fingeringInfo.orientation === 0) {
- getAPPData("left");
- }
- };
- const getNotes = () => {
- const fignerData = FIGNER_INSTRUMENT_DATA[data.subject as keyof typeof FIGNER_INSTRUMENT_DATA];
- if (fignerData) {
- data.tones = fignerData.tones || [];
- if (data.tones.length) {
- data.activeTone = data.tones[0];
- data.popupActiveTone = data.tones[0];
- }
- data.tips = fignerData.tips || [];
- setNotes();
- setTimeout(() => {
- data.loading = false;
- }, 600);
- }
- };
- const setNotes = () => {
- const fignerData = FIGNER_INSTRUMENT_DATA[data.subject as keyof typeof FIGNER_INSTRUMENT_DATA];
- if (fignerData) {
- const tempNotes = fignerData[`list${data.activeTone.realName || ""}`];
- const appendNote: any = [];
- tempNotes.forEach((note: any) => {
- note.steps = new Array(Math.abs(note.step)).fill(1);
- if (FIGNER_INSTRUMENT_REALKEY.includes(note.realKey)) {
- appendNote.push(note);
- }
- });
- // 判断是音符状态
- data.notes = data.noteType === "#c" ? appendNote : tempNotes;
- // data.notes = fignerData[`list${data.activeTone.realName || ""}`];
- data.notePoints = FINER_INSTRUMENT_POINT[data.subject];
- }
- };
- const getFingeringData = async () => {
- const subject: any = data.subject + (data.viewIndex === 0 ? "" : data.viewIndex);
- console.log("🚀 ~ subject:模式", subject, data.viewIndex, data.fingeringMode);
- fingerData.subject = await getFingeringConfig(subject);
- };
- const createAudio = (url: string) => {
- return new Promise((resolve, reject) => {
- const noteAudio = new Howl({
- src: url,
- loop: true,
- onload: () => {
- resolve(noteAudio);
- },
- onloaderror: () => {
- reject(new Error(`加载音频失败`));
- },
- });
- });
- };
- const getSounFonts = async () => {
- const pathname = /(192|localhost)/.test(location.origin) ? "/" : location.pathname;
- data.loadingSoundFonts = true;
- try {
- data.loadingSoundProgress = 0;
- for (let i = 0; i < data.notes.length; i++) {
- const note = data.notes[i];
- // console.log("🚀 ~ note:", i);
- let url = `${pathname}soundfonts/${data.subject}/`;
- url += note.realName;
- url += ".mp3";
- data.soundFonts[note.realKey] = await createAudio(url);
- data.loadingSoundProgress = Math.floor(((i + 1) / data.notes.length) * 100);
- }
- data.loadingSoundProgress = 100;
- } catch (e: any) {
- //
- showToast(e.message);
- }
- api_cloudLoading();
- data.loadingSoundFonts = false;
- };
- // const selectSubjectType = (subject: string) => {
- // data.subjects.forEach((item: any) => {
- // if (item.value === subject) {
- // item.className = styles.selected;
- // } else {
- // item.className = "";
- // }
- // });
- // };
- // 切换当前模式
- const onChangeFingeringModel = (e: any) => {
- e.stopPropagation();
- //
- if (playAction.listenLock) return;
- if (playAction.showAnswerLoading) return;
- data.loadingImg = true;
- if (data.fingeringMode === "scaleMode") {
- if (["pan-flute", "ocarina", "whistling"].includes(data.subject)) {
- data.viewIndex = 1;
- } else {
- data.viewIndex = 0;
- }
- const o: any = {
- "pan-flute": 2,
- ocarina: 2,
- whistling: 2,
- piccolo: 2,
- "hulusi-flute": 2,
- "baroque-recorder": 2,
- };
- data.viewTotal = o[data.subject] || 1;
- data.fingeringMode = "listenMode";
- } else if (data.fingeringMode === "listenMode") {
- data.fingeringMode = "fingeringMode";
- } else if (data.fingeringMode === "fingeringMode") {
- data.fingeringMode = "scaleMode";
- data.viewIndex = 0;
- data.noteType = "all";
- }
- data.tipShow = false;
- resetElement();
- resetMode(true, 0);
- setTimeout(() => {
- __init(false);
- }, 100);
- };
- const __init = async (loadSong = true) => {
- data.loadingDom = true;
- getNotes();
- // selectSubjectType(data.subject);
- if (data.fingeringMode === "fingeringMode") {
- if (data.subject === "pan-flute") {
- data.viewIndex = 3;
- } else if (["pan-flute", "ocarina", "melodica", "whistling"].includes(data.subject)) {
- data.viewIndex = 1;
- }
- } else {
- if (["pan-flute", "ocarina", "whistling"].includes(data.subject)) {
- data.viewIndex = 1;
- }
- }
- // 音阶模式 默认设置正反面
- if(data.fingeringMode === "scaleMode"){
- if(["hulusi-flute", "ocarina", "whistling", "piccolo", "baroque-recorder"].includes(data.subject)){
- data.viewIndex = 2;
- }
- }
- const o: any = {
- "pan-flute": 2,
- ocarina: 2,
- whistling: 2,
- piccolo: 2,
- "hulusi-flute": 2,
- "baroque-recorder": 2,
- };
- data.viewTotal = o[data.subject] || 1;
- getFingeringData();
- getHeadTop();
- if (loadSong) {
- await getSounFonts();
- }
- data.loadingDom = false;
- data.loadingImg = false;
- // 初始化获取元素宽高
- onResize();
- };
- // 获取声部
- const getSubjects = async () => {
- try {
- // api_subjectList
- // const subjects = await api_musicalInstrumentList({
- // enableFlag: true,
- // });
- // const rows = subjects.data || [];
- // rows.forEach((row: any) => {
- // const tempList: any = {
- // text: row.name,
- // value: mappingVoicePart(row.code, "INSTRUMENT"), // mappingVoicePart(row.code, "INSTRUMENT"),
- // id: row.id,
- // };
- // data.subjects.push(tempList);
- // });
- const subjects = await api_subjectList({
- enableFlag: true,
- delFlag: 0,
- page: 1,
- rows: 999,
- });
- const rows = subjects.data || [];
- const tempSubjects: any[] = [];
- rows.forEach((row: any) => {
- const tempList: any = {
- text: row.name,
- value: "", // mappingVoicePart(row.code, "INSTRUMENT"),
- id: row.id,
- children: [] as any,
- };
- if (Array.isArray(row.instruments)) {
- row.instruments.forEach((i: any) => {
- const code = i.code ? i.code.split(",") : [];
- tempList.children.push({
- text: i.name,
- id: i.id,
- value: mappingVoicePart(code[0] || "", "INSTRUMENT"),
- });
- });
- }
- tempSubjects.push(tempList);
- });
- console.log(data.subject, "data.subject");
- data.subjects = tempSubjects;
- } catch (e) {
- //
- console.log(e, "e");
- }
- };
- onBeforeMount(async () => {
- if (browser().isApp) {
- state.platform = "APP" as IPlatform;
- } else {
- state.platform = query.platform?.toLocaleUpperCase() || "";
- }
- if (state.platform === IPlatform.PC) {
- document.title = "听音练习";
- }
- await getSubjects();
- __init();
- });
- // 播放时间
- let noteTimer: any = null;
- /**
- * 播放音频
- * @param item 音频节点
- * @param showNote 是否显示对应的指法
- * @param isScrollShowNote 是否滚动到对应播放的位置
- * @param autoStop 是否自动停止
- * @returns
- */
- const noteClick = (item: IFIGNER_INSTRUMENT_Note, showNote = true, isScrollShowNote = false, autoStop = false, callBack?: any) => {
- // console.log('音高', item.realKey)
- if (data.noteAudio) {
- data.noteAudio.stop();
- if (data.realKey === item.realKey) {
- data.realKey = 0;
- data.noteAudio = null as unknown as Howl;
- return;
- }
- clearTimeout(noteTimer);
- }
- if (showNote) {
- data.realKey = item.realKey;
- }
- // console.log("key:", item.realKey, data.soundFonts);
- data.noteAudio = data.soundFonts[item.realKey];
- if (data.noteAudio) {
- clearTimeout(noteTimer);
- data.noteAudio.play();
- if (isScrollShowNote) scrollAnswer(item.realKey);
- // 判断是否自动停止播放停止
- if (autoStop) return;
- noteTimer = setTimeout(() => {
- handleStop();
- if (callBack && typeof callBack === "function") {
- callBack(item);
- }
- }, 300);
- }
- };
- const handleStop = () => {
- if (data.noteAudio) {
- data.noteAudio.stop();
- data.realKey = 0;
- data.noteAudio = null as unknown as Howl;
- }
- };
- const isLongPress = ref(false); // 是否长按
- const isTouchStart = ref(false); // 是否长按
- let isTouch = false;
- let timerNoteId: any;
- const longPressDuration = 200;
- const onLongPress = () => {
- console.log("长按检测成功!");
- isLongPress.value = true;
- clearTimeout(noteTimer);
- };
- // 开始长按检测
- const startNotePress = async (note: any, isScrollShowNote = true) => {
- if (playStatus.gamut) return;
- if (playAction.listenLock) return;
- if (playAction.showAnswerLoading) return;
- timerNoteId = setTimeout(onLongPress, longPressDuration);
- // 为了处理希沃白板垃圾事件
- if (isTouchStart.value) return;
- isTouchStart.value = true;
- if (playStatus.action) {
- playAction.userAnswer = note;
- // 判断用户答题
- const userResult = note.realKey === playAction.standardAnswer.realKey ? 1 : 2;
- playAction.userAnswerStatus = userResult;
- playAction.listenLock = true;
- data.realKey = note.realKey;
- noteClick(note, true, isScrollShowNote, false, playCallBack);
- } else {
- handleStop();
- noteClick(note, true, isScrollShowNote);
- }
- };
- // 取消长按检测
- const cancelNotePress = async (note: any, isScrollShowNote = true) => {
- if (timerNoteId !== null) {
- clearTimeout(timerNoteId);
- timerNoteId = null;
- }
- if (isLongPress.value) {
- handleStop();
- playCallBack(note);
- }
- if (isLongPress.value) {
- isLongPress.value = false;
- }
- isTouchStart.value = false;
- console.log(isLongPress.value, timerNoteId, note.realName);
- };
- const playCallBack = (note: any) => {
- if (playAction.listenLock) {
- const userResult = note.realKey === playAction.standardAnswer.realKey ? 1 : 2;
- resetMode(userResult === 1 ? true : false, 0);
- data.realKey = 0;
- // 如果是指法模式显示完之后要还原
- if (data.fingeringMode === "fingeringMode" && userResult === 2) {
- // 延迟显示,因为重置的时候有一个异步操作
- setTimeout(() => {
- data.realKey = playAction.standardAnswer.realKey;
- }, 10);
- }
- playAction.listenLock = false;
- }
- };
- /** 点击音符播放 */
- const noteInstrumentPlay = async (note: any, isScroll = false) => {
- // 判断是否在播放音阶
- if (playStatus.gamut) return;
- if (playAction.listenLock) return;
- if (playAction.showAnswerLoading) return;
- if (playStatus.action) {
- playAction.userAnswer = note;
- // 判断用户答题
- const userResult = note.realKey === playAction.standardAnswer.realKey ? 1 : 2;
- playAction.userAnswerStatus = userResult;
- playAction.listenLock = true;
- data.realKey = note.realKey;
- await fingeringPlay(note, 1000);
- resetMode(userResult === 1 ? true : false, 0);
- data.realKey = 0;
- // 如果是指法模式显示完之后要还原
- if (data.fingeringMode === "fingeringMode" && userResult === 2) {
- // 延迟显示,因为重置的时候有一个异步操作
- setTimeout(() => {
- data.realKey = playAction.standardAnswer.realKey;
- }, 10);
- }
- playAction.listenLock = false;
- } else {
- noteClick(note, true, isScroll);
- }
- };
- /** 返回 */
- const handleBack = () => {
- // platform: query.platform,
- handleStop();
- if (props.isComponent) {
- // 返回的时候默认横屏
- // api_setRequestedOrientation(0);
- emit("close");
- return;
- } else if (state.platform === IPlatform.PC) {
- console.log(1, query);
- if (query.matchMedia == 1) {
- // 老师端,首页
- window.parent.postMessage(
- {
- api: "iframe_exit",
- },
- "*"
- );
- return;
- } else {
- window.close();
- return;
- }
- // if (fingerData.fingeringInfo.orientation === 0) {
- // api_setRequestedOrientation(1);
- // }
- }
- // 不在APP中,
- if (!storeData.isApp) {
- window.close();
- return;
- }
- api_back();
- };
- // 排箫,默认0.9显示
- const setDefaultScale = () => {
- if (data.subject === "pan-flute") {
- data.transform.scale = 0.9;
- data.transform.startScale = 0.9;
- }
- };
- onMounted(() => {
- loadElement();
- api_setStatusBarVisibility();
- });
- // 判断两个元素是否重叠
- const isElementOverlapping = (el1: any, el2: any) => {
- const rect1 = el1?.getBoundingClientRect();
- const rect2 = el2?.getBoundingClientRect();
- return !(rect1.right < rect2.left || rect1.left > rect2.right || rect1.bottom < rect2.top || rect1.top > rect2.bottom);
- };
- // 是否在拖拽
- const isDragging = ref(false);
- const loadElement = () => {
- const fingeringContainer = document.getElementById("fingeringContainer");
- setDefaultScale();
- // console.log("🚀 ~ fingeringContainer:", fingeringContainer);
- const mc = new Hammer.Manager(fingeringContainer as HTMLElement);
- mc.add(new Hammer.Pan({ threshold: 0, pointers: 0 }));
- mc.add(new Hammer.Pinch({ threshold: 0 })).recognizeWith([mc.get("pan")]);
- let dragTimeout: any;
- mc.on("panstart pinchstart", function (ev) {
- isDragging.value = true;
- clearTimeout(dragTimeout);
- data.transform.transition = "";
- });
- mc.on("panmove pinchmove", function (ev) {
- if (ev.type === "pinchmove") {
- // console.log("🚀 ~ ev:", ev.type, ev.scale, ev.deltaX, ev.deltaY);
- data.transform.scale = ev.scale * data.transform.startScale;
- data.transform.x = data.transform.startX + ev.deltaX;
- data.transform.y = data.transform.startY + ev.deltaY;
- // 使用示例
- const element1 = document.getElementById("fullInstrumentImg");
- const element2 = document.getElementById("fullInstrumentUserTab");
- data.domOverlapping = isElementOverlapping(element1, element2);
- }
- if (ev.type === "panmove") {
- // console.log("🚀 ~ ev:", ev.type, ev.deltaX, ev.deltaY);
- data.transform.x = data.transform.startX + ev.deltaX;
- data.transform.y = data.transform.startY + ev.deltaY;
- // 使用示例
- const element1 = document.getElementById("fullInstrumentImg");
- const element2 = document.getElementById("fullInstrumentUserTab");
- data.domOverlapping = isElementOverlapping(element1, element2);
- }
- });
- mc.on("panend pinchend", function (ev) {
- dragTimeout = setTimeout(() => {
- isDragging.value = false;
- }, 100); // 设置一个短暂的延迟以确保拖拽操作结束
- });
- //
- mc.on("hammer.input", function (ev) {
- if (ev.isFinal) {
- // isDragging.value = false;
- data.transform.startScale = data.transform.scale;
- data.transform.startX = data.transform.x;
- data.transform.startY = data.transform.y;
- // 使用示例
- const element1 = document.getElementById("fullInstrumentImg");
- const element2 = document.getElementById("fullInstrumentUserTab");
- data.domOverlapping = isElementOverlapping(element1, element2);
- }
- });
- };
- const resetElement = () => {
- data.transform.transition = "all 0.3s";
- nextTick(() => {
- data.transform.scale = data.subject === "pan-flute" ? 0.9 : 1;
- data.transform.x = 0;
- data.transform.y = 0;
- data.transform.startScale = data.subject === "pan-flute" ? 0.9 : 1;
- data.transform.startX = 0;
- data.transform.startY = 0;
- data.domOverlapping = false;
- });
- };
- // 判断乐器是否移动
- const instrumentTranstion = computed(() => {
- const transform = data.transform;
- let scale = 1;
- if (data.subject === "pan-flute") {
- scale = 0.9;
- }
- if (transform.scale !== scale || transform.x !== 0 || transform.y !== 0 || transform.startScale !== scale || transform.startX !== 0 || transform.startY !== 0) {
- return true;
- } else {
- return false;
- }
- });
- const pageVisible = usePageVisibility();
- watch(
- () => pageVisible.value,
- (val) => {
- if (val === "hidden") {
- clearTimeout(playAction.timer);
- playAction.listenLock = false;
- playAction.listenTipsStatus = false;
- playAction.exampleAnser = {};
- resetMode(true, 0);
- handleStop();
- gaumntPause();
- }
- }
- );
- watch(
- () => data.tipShow,
- (val: any) => {
- if (!val) {
- onResize();
- }
- }
- );
- /** 课件播放 */
- const changePlay = (res: any) => {
- if (res?.data?.api === "setPlayState") {
- clearTimeout(playAction.timer);
- playAction.listenLock = false;
- playAction.listenTipsStatus = false;
- playAction.exampleAnser = {};
- resetMode(true, 0);
- handleStop();
- gaumntPause();
- // 重置乐器
- if (res?.data?.data?.code) {
- data.subject = code;
- data.viewIndex = 0;
- data.tipShow = false;
- data.loadingDom = true;
- fingerData.fingeringInfo = subjectFingering(data.subject);
- data.activeTone = {} as any;
- data.popupActiveTone = {} as any;
- resetElement();
- // 设置屏幕方向
- setTimeout(() => {
- __init();
- }, 100);
- }
- } else if (res.data.api === "startPlayState") {
- onStartPlayState();
- }
- };
- const onStartPlayState = () => {
- if (!localStorage.getItem("fingerGuideKey")) return;
- if (!(props.show && !data.loading && !data.loadingSoundFonts)) return;
- if (data.changeSubjectShow) return;
- if (data.fingeringMode === "fingeringMode" || data.fingeringMode === "listenMode") {
- onActionPlay();
- }
- };
- const noteBoxRef = ref();
- const scrollNoteBox = (type: "left" | "right") => {
- const domOffsetWidth = noteBoxRef.value.offsetWidth;
- const width = domOffsetWidth / 2;
- const scrollLeft: any = noteBoxRef.value.scrollLeft;
- // 判断是否移动到最左边
- if (width >= scrollLeft && type === "left") {
- // 不管当前显示在哪个音老师滚动到开始位置
- (noteBoxRef.value as unknown as HTMLElement).scroll({
- left: 0,
- top: 0,
- behavior: "smooth",
- });
- return;
- }
- // 处理在部分手机点击左右会超出范围
- if (type === "right") {
- // 遍历子元素并累加它们的宽度
- let childElementsWidth = 0;
- for (let i = 0; i < noteBoxRef.value.children.length; i++) {
- childElementsWidth += noteBoxRef.value.children[i].offsetWidth;
- }
- // 判断是否移动到最右边
- if (width > childElementsWidth - scrollLeft - domOffsetWidth) {
- // 不管当前显示在哪个音老师滚动到开始位置
- (noteBoxRef.value as unknown as HTMLElement).scroll({
- left: noteBoxRef.value.scrollWidth,
- top: 0,
- behavior: "smooth",
- });
- return;
- }
- }
- (noteBoxRef.value as unknown as HTMLElement).scrollBy({
- left: type === "left" ? -width : width,
- behavior: "smooth",
- });
- };
- const playStatus = reactive({
- gamut: false, // 是否播放音阶
- gamutTimer: null as any, // 播放音阶定时器
- answer: false, // 是否显示答案
- action: false, // 是否开始播放
- });
- /** 音符切换 */
- const noteChangeShow = () => {
- if (playStatus.action) {
- if (playAction.listenLock) return;
- playAction.resetAction = true;
- resetMode(true, 0);
- }
- // // 播放音阶时不能切换
- // if (playStatus.gamut) return;
- // // 开始答题不能切换
- // if (playStatus.action) return;
- playStatus.gamut = false;
- gaumntPause();
- if (data.noteType === "all") {
- data.noteType = "#c";
- } else {
- data.noteType = "all";
- }
- getNotes();
- setTimeout(() => {
- (noteBoxRef.value as unknown as HTMLElement).scroll({
- left: 0,
- top: 0,
- behavior: "smooth",
- });
- }, 0);
- setTimeout(() => {
- playAction.resetAction = false;
- }, 2000);
- };
- // 开始播放音阶
- const onGamutPlayOrPause = async () => {
- playAction.resetAction = false;
- if (playStatus.gamut) {
- playStatus.gamut = false;
- gaumntPause();
- } else {
- // 不管当前显示在哪个音老师滚动到开始位置
- (noteBoxRef.value as unknown as HTMLElement).scroll({
- left: 0,
- top: 0,
- behavior: "smooth",
- });
- playStatus.gamut = true;
- const notes = data.notes;
- let scrollCount = 0;
- for (let i = 0; i < notes.length; i++) {
- if (!playStatus.gamut) return false;
- const activeDom = document.querySelectorAll(".note-class")[i] as any;
- if (activeDom.offsetLeft >= noteBoxRef.value.offsetWidth + (noteBoxRef.value.offsetWidth / 2) * scrollCount - activeDom.offsetWidth) {
- scrollNoteBox("right");
- scrollCount++;
- }
- await gaumtPlay(notes[i]);
- }
- // // 处理播放到最后一个
- setTimeout(() => {
- playStatus.gamut = false;
- gaumntPause();
- }, 667);
- }
- };
- const gaumtPlay = (note: any, status?: boolean) => {
- return new Promise((resolve) => {
- playStatus.gamutTimer = setTimeout(() => {
- if (playStatus.gamut || status) {
- noteClick(note);
- }
- resolve(note);
- }, 667);
- });
- };
- const gaumntPause = () => {
- clearTimeout(playStatus.gamutTimer);
- if (data.noteAudio) {
- data.noteAudio.stop();
- data.realKey = 0;
- data.noteAudio = null as unknown as Howl;
- }
- };
- /** 开始播放 */
- const playAction = reactive({
- exampleAnser: {} as any, // 示例声音
- standardAnswer: {} as any, // 标准答案key
- showAnswerLoading: false, // 显示按答案中
- listenModeStatus: false, // 是否开始了模式
- listenLock: false,
- listenTipsStatus: false, // 开始播放状态
- resetAction: false, // 是否重置
- /** 0: 未答,1: 答对,2: 答错 */
- userAnswerStatus: 0 as 0 | 1 | 2, // 用户回答状态
- userAnswer: {} as any, // 用户答的数据
- timer: null as any,
- });
- const onActionPlay = async () => {
- playAction.resetAction = false;
- if (playAction.listenLock) return;
- if (playAction.showAnswerLoading) return;
- playStatus.action = true;
- playStatus.answer = true;
- // 先暂停播放声音
- gaumntPause();
- if (data.fingeringMode === "fingeringMode") {
- onFingeringMode();
- } else if (data.fingeringMode === "listenMode") {
- if (playAction.listenModeStatus) {
- playAction.listenLock = true;
- await fingeringPlay(playAction.standardAnswer, 1500, false);
- gaumntPause();
- playAction.listenLock = false;
- } else {
- onListenMode();
- }
- }
- };
- // 指法模式
- const fingeringPlay = (note: any, timer = 1500, showNote = true) => {
- return new Promise((resolve) => {
- noteClick(note, showNote);
- playAction.timer = setTimeout(() => {
- resolve(note);
- }, timer);
- });
- };
- const onFingeringMode = () => {
- const randomIndex = Math.floor(Math.random() * data.notes.length);
- playAction.standardAnswer = data.notes[randomIndex];
- data.realKey = data.notes[randomIndex].realKey;
- if (playAction.listenModeStatus) {
- return;
- }
- playAction.listenModeStatus = true; // 是否开始听音
- playAction.listenLock = true; // 锁
- playAction.listenTipsStatus = true;
- playAction.timer = setTimeout(() => {
- playAction.listenTipsStatus = false;
- playAction.listenLock = false; // 锁
- }, 2000);
- };
- // 听音模式
- const onListenMode = async () => {
- playAction.listenModeStatus = true; // 是否开始听音
- playAction.listenLock = true; // 锁
- playAction.listenTipsStatus = true;
- // 设置并保存示例数据
- let randomIndex = data.notes.findIndex((item: any) => item.realKey === 69); // Math.floor(Math.random() * data.notes.length);
- playAction.exampleAnser = data.notes[randomIndex];
- data.realKey = playAction.exampleAnser.realKey;
- scrollAnswer(playAction.exampleAnser.realKey);
- await fingeringPlay(playAction.exampleAnser);
- data.realKey = 0;
- playAction.exampleAnser = {};
- gaumntPause();
- playAction.timer = setTimeout(async () => {
- // 设置答题数据
- randomIndex = Math.floor(Math.random() * data.notes.length);
- playAction.standardAnswer = data.notes[randomIndex];
- await fingeringPlay(data.notes[randomIndex], 1500, false);
- gaumntPause();
- playAction.listenLock = false;
- playAction.listenTipsStatus = false;
- }, 1000);
- };
- // 显示答案
- const onShowAnswer = async () => {
- if (playAction.listenLock) return;
- playAction.showAnswerLoading = true;
- scrollAnswer(playAction.standardAnswer.realKey);
- await fingeringPlay(playAction.standardAnswer);
- resetMode(true, 0);
- // }
- };
- // 滚动到对应答案位置
- const scrollAnswer = (realKey?: any) => {
- const tempRealKey = realKey || data.realKey;
- const index = data.notes.findIndex((item: any) => item.realKey === tempRealKey);
- const activeDom = document.querySelectorAll(".note-class")[index] as any;
- if (activeDom) {
- const aWidth = activeDom.offsetWidth;
- const width = noteBoxRef.value.offsetWidth;
- const aLeft = Math.max(activeDom?.offsetLeft - aWidth, 0);
- (noteBoxRef.value as unknown as HTMLElement).scroll({
- left: Math.max(aLeft - width / 2, 0),
- top: 0,
- behavior: "smooth",
- });
- }
- };
- /**
- * 重置播放状态
- * @param status 是否全部重置
- * @param timer 延时时长(默认2s)
- */
- const resetMode = (status = true, timer = 2000) => {
- // 2秒钟后重置
- setTimeout(() => {
- gaumntPause();
- if (status) {
- playAction.standardAnswer = {};
- playAction.showAnswerLoading = false;
- playAction.userAnswerStatus = 0;
- playAction.userAnswer = {};
- playAction.listenModeStatus = false;
- playStatus.action = false;
- playStatus.answer = false;
- playStatus.gamut = false;
- data.realKey = 0;
- } else {
- playAction.userAnswerStatus = 0;
- playAction.userAnswer = {};
- }
- }, timer);
- };
- /** 滚轮缩放 */
- const handleWheel = (e: WheelEvent) => {
- e.preventDefault();
- if (e.deltaY > 0) {
- data.transform.scale -= 0.1;
- if (data.transform.scale <= 0.5) {
- data.transform.scale = 0.5;
- }
- } else {
- data.transform.scale += 0.1;
- if (data.transform.scale >= 2) {
- data.transform.scale = 2;
- }
- }
- // 使用示例
- setTimeout(() => {
- const element1 = document.getElementById("fullInstrumentImg");
- const element2 = document.getElementById("fullInstrumentUserTab");
- data.domOverlapping = isElementOverlapping(element1, element2);
- }, 0);
- };
- const onResize = () => {
- nextTick(() => {
- setTimeout(() => {
- const element1: any = document.querySelector("#fullInstrumentImg");
- // console.log(element1, "element1");
- const rect = element1?.getBoundingClientRect();
- data.domOverImgPropery = {
- ...rect,
- width: rect.width * (1 / data.transform.scale) + "px",
- height: rect.height * (1 / data.transform.scale) + "px",
- };
- }, 330);
- });
- };
- onMounted(() => {
- window.addEventListener("message", changePlay);
- window.addEventListener("resize", onResize);
- const fingeringContainer = document.getElementById("fingeringContainer");
- fingeringContainer?.addEventListener("wheel", handleWheel);
- document.addEventListener("keydown", (e: KeyboardEvent) => {
- if (e.code === "Tab") {
- e.stopPropagation();
- e.preventDefault();
- // onStartPlayState();
- // 判断是否在应用中
- window.parent.postMessage(
- {
- api: "documentBodyKeyup",
- code: "Tab",
- },
- "*"
- );
- }
- });
- });
- onUnmounted(() => {
- window.removeEventListener("message", changePlay);
- window.removeEventListener("resize", onResize);
- const fingeringContainer = document.getElementById("fingeringContainer");
- fingeringContainer?.removeEventListener("wheel", handleWheel);
- document.title = "Ai学练";
- });
- const containerBox = computed(() => {
- if (state.platform === IPlatform.PC || query.modelType) {
- return {
- paddingTop: "1.3rem",
- paddingBottom: "",
- };
- }
- if (data.fingeringMode === "scaleMode") {
- if (data.subject === "hulusi-flute") {
- return {
- paddingTop: "1.3rem",
- paddingBottom: ".5rem",
- };
- } else if (data.subject === "piccolo" || data.subject === "baroque-recorder") {
- return {
- paddingTop: "1.3rem",
- paddingBottom: ".5rem",
- };
- } else if (data.subject === "pan-flute") {
- return {
- paddingTop: "1.3rem",
- paddingBottom: "0",
- };
- } else if (data.subject === "ocarina" || data.subject === "whistling") {
- return {
- paddingTop: "1.3rem",
- paddingBottom: "0",
- };
- } else if (data.subject === "melodica") {
- return {
- paddingTop: "1.8rem",
- paddingBottom: "0.2rem",
- };
- } else {
- return {
- paddingTop: "",
- paddingBottom: "",
- };
- }
- } else {
- if (data.subject === "hulusi-flute") {
- return {
- paddingTop: "1.3rem",
- paddingBottom: "0rem",
- };
- } else if (data.subject === "piccolo" || data.subject === "baroque-recorder") {
- return {
- paddingTop: "1.3rem",
- paddingBottom: ".5rem",
- };
- } else if (data.subject === "pan-flute") {
- return {
- paddingTop: "1.3rem",
- paddingBottom: "0",
- };
- } else if (data.subject === "ocarina" || data.subject === "whistling") {
- return {
- paddingTop: "1.3rem",
- paddingBottom: "0",
- };
- } else if (data.subject === "melodica") {
- return {
- paddingTop: "1.8rem",
- paddingBottom: "0.2rem",
- };
- } else {
- return {
- paddingTop: "",
- paddingBottom: "",
- };
- }
- }
- });
- const listenText = computed(() => {
- if (data.fingeringMode === "fingeringMode") {
- if (playStatus.action) {
- return "换一换";
- } else {
- return "开始练习";
- }
- } else if (data.fingeringMode === "listenMode") {
- if (playStatus.action) {
- return "再听一遍";
- } else {
- return "开始听音";
- }
- }
- return "开始听音";
- });
- const modeText = computed(() => {
- let text = "";
- let icon = icons.icon_mode;
- data.fingeringModeList.forEach((item: any) => {
- if (item.value === data.fingeringMode) {
- text = item.text;
- icon = item.icon;
- }
- });
- return {
- text,
- icon,
- };
- });
- // 屏幕方向 0 竖,1 横
- const orientationDirection = computed(() => {
- return ["hulusi-flute", "piccolo", "baroque-recorder"].includes(data.subject) ? 1 : 0;
- });
- const resultImg = (note: any) => {
- if (data.realKey === note.realKey && !playStatus.action) {
- return {
- icon: icons.icon_btn_ylow,
- status: false,
- };
- } else if (playAction.exampleAnser.realKey === note.realKey) {
- return {
- icon: icons.icon_btn_ylow,
- status: false,
- };
- } else if (playAction.standardAnswer.realKey === note.realKey) {
- // 没有开始答题
- if (!playStatus.action) {
- return {
- icon: icons.icon_btn_ylow,
- status: false,
- };
- }
- // 显示答案中
- if (playAction.showAnswerLoading) {
- return {
- icon: icons.icon_btn_green,
- status: true,
- };
- }
- // 用户答对
- if (playAction.userAnswerStatus === 1) {
- return {
- icon: icons.icon_btn_green,
- status: true,
- };
- }
- } else {
- // 用户答错
- if (playAction.userAnswerStatus === 2 && playAction.userAnswer.realKey === note.realKey) {
- return {
- icon: icons.icon_btn_red,
- status: true,
- };
- }
- }
- return {
- icon: icons.icon_btn_blue,
- status: true,
- };
- };
- const userTabActive = ref<"1" | "2">("1");
- const userTabs = [
- {
- name: "音阶",
- value: "1",
- },
- {
- name: "功能",
- value: "2",
- },
- ];
- // 引导页
- const { guidanceShow, setGuidanceShow } = useDragGuidance();
- // 切换乐器弹窗
- let changeSubjectShowBoxDragData: any;
- let changeSubjectShowBoxClass: string;
- if (query.platform === "pc") {
- changeSubjectShowBoxClass = "changeSubjectShowBoxClass_drag";
- changeSubjectShowBoxDragData = useDrag([`${changeSubjectShowBoxClass} .dragTopBox`, `${changeSubjectShowBoxClass} .dragbomBox`], changeSubjectShowBoxClass, toRef(data, "changeSubjectShow"), storeData.user.id as string);
- }
- // 移调弹窗
- let tnoteShowBoxDragData: any;
- let tnoteShowBoxClass: string;
- if (query.platform === "pc") {
- tnoteShowBoxClass = "tnoteShowBoxClass_drag";
- tnoteShowBoxDragData = useDrag([`${tnoteShowBoxClass} .dragTopBox`, `${tnoteShowBoxClass} .dragbomBox`], tnoteShowBoxClass, toRef(data, "tnoteShow"), storeData.user.id as string);
- }
- return () => {
- const relationship = fingerData.subject?.relationship?.[data.realKey] || [];
- const rs: number[] = Array.isArray(relationship[1]) ? relationship[fingerData.relationshipIndex] : relationship;
- const canTizhi = Array.isArray(relationship[1]);
- return (
- <div
- class={[styles.fingerBox, state.platform !== IPlatform.PC && !query.modelType && fingerData.fingeringInfo.orientation === 1 ? styles.fingerBottom : styles.fingerRight, data.linkSource === "class" ? styles.linkSourceClass : ""]}
- onClick={() => {
- if (data.linkSource === "class") {
- window.parent.postMessage(
- {
- api: "clickViewFigner",
- },
- "*"
- );
- }
- }}
- >
- {/* 老师端过来隐藏 */}
- {query.platform !== "pc" && (
- <div
- class={styles.head}
- style={{
- paddingTop: data.paddingTop && !browser().ios ? data.paddingTop : "",
- paddingLeft: data.paddingLeft && !browser().ios ? data.paddingLeft : "",
- }}
- >
- <div class={styles.left}>
- <button class={[styles.backBtn]} onClick={() => handleBack()}>
- <img src={icons.icon_back} />
- </button>
- <div
- class={[styles.baseBtn, styles.changeInstrumentBtn]}
- onClick={(e) => {
- e.stopPropagation();
- //
- // 播放音阶时不能切换
- if (playStatus.gamut) {
- return;
- }
- // 开始答题不能切换
- if (playAction.listenLock) {
- return;
- }
- data.changeSubjectShow = true;
- }}
- >
- <img src={icons.icon_change_instrument} />
- <span>切换乐器</span>
- </div>
- <div class={styles.baseBtn} onClick={onChangeFingeringModel}>
- <img src={modeText.value.icon} />
- <span>{modeText.value.text}</span>
- </div>
- {/* */}
- </div>
- {/* */}
- </div>
- )}
- <div
- class={styles.fingerContent}
- style={{
- paddingTop: data.paddingTop ? data.paddingTop : "",
- paddingLeft: data.paddingLeft ? data.paddingLeft : "",
- }}
- >
- <div class={styles.wrapFinger}>
- <div
- id="fingeringContainer"
- class={[styles.boxFinger, query.platform === "pc" ? styles.pcBoxFinger : "", data.domOverlapping && data.notePoints?.length > 0 && styles.boxFingerOverlapping]}
- style={{
- paddingTop: containerBox.value.paddingTop,
- paddingBottom: containerBox.value.paddingBottom,
- }}
- >
- <div
- style={{
- transform: `translate3d(${data.transform.x}px,${data.transform.y}px,0px) scale(${data.transform.scale})`,
- transition: data.transform.transition,
- }}
- class={[styles.fingeringContainer]}
- >
- <div class={styles.imgs}>
- {!data.loadingImg && <img id="fullInstrumentImg" src={data.fingeringMode === "scaleMode" ? fingerData.subject?.json?.full : fingerData.subject?.json?.full1} />}
- {rs.map((key: number | string, index: number) => {
- const nk: string = typeof key === "string" ? key.replace("active-", "") : String(key);
- return <img class={styles.showImgNk} data-index={nk} src={fingerData.subject?.json?.[nk]} />;
- })}
- <div style={{ left: data.viewIndex == 2 ? "0" : "64%" }} class={[styles.tizhi, canTizhi && styles.canDisplay]} onClick={() => (fingerData.relationshipIndex = fingerData.relationshipIndex === 0 ? 1 : 0)}>
- 替指
- </div>
- <div id="finger-note-2" style={{ left: "50%", transform: "translateX(-50%)" }} class={styles.tizhi} onClick={() => (fingerData.relationshipIndex = fingerData.relationshipIndex === 0 ? 1 : 0)}></div>
- {data.notePoints?.length > 0 && (
- <div
- class={[styles.fingeringPointSection]}
- style={{
- width: data.domOverImgPropery.width,
- height: data.domOverImgPropery.height,
- }}
- >
- <div class={[styles[data.subject], data.viewIndex === 2 && data.subject === "pan-flute" && styles["pan-flute-back"]]}>
- {data.notePoints.map((point: any) => (
- <div
- class={styles.p1}
- style={point.style}
- // onClick={(e: any) => {
- // e.stopPropagation();
- // if (isDragging.value) return;
- // noteInstrumentPlay(point, true);
- // }}
- onMousedown={(e: any) => {
- e.stopPropagation();
- e.preventDefault();
- console.log("onMousedown", e);
- if (isTouch) return;
- startNotePress(point);
- }}
- onMouseup={(e: any) => {
- e.stopPropagation();
- e.preventDefault();
- // console.log("onMouseup", e);
- if (isTouch) return;
- cancelNotePress(point);
- }}
- onMouseleave={(e: any) => {
- e.stopPropagation();
- e.preventDefault();
- // console.log("onMouseleave", e);
- if (isTouch) return;
- cancelNotePress(point);
- }}
- onTouchstart={(e: any) => {
- e.stopPropagation();
- e.preventDefault();
- // console.log("onTouchstart", e);
- isTouch = true;
- startNotePress(point);
- }}
- onTouchend={(e: any) => {
- e.stopPropagation();
- e.preventDefault();
- // console.log("onTouchend", e);
- cancelNotePress(point);
- }}
- onTouchcancel={(e: any) => {
- e.stopPropagation();
- e.preventDefault();
- // console.log("onTouchcancel", e);
- cancelNotePress(point);
- }}
- >
- {point.children && (
- <div
- class={styles.p2}
- // onClick={(e: any) => {
- // e.stopPropagation();
- // if (isDragging.value) return;
- // noteInstrumentPlay(point.children, true);
- // }}
- onMousedown={(e: any) => {
- e.stopPropagation();
- e.preventDefault();
- if (isTouch) return;
- startNotePress(point.children);
- }}
- onMouseup={(e: any) => {
- e.stopPropagation();
- e.preventDefault();
- if (isTouch) return;
- cancelNotePress(point.children);
- }}
- onMouseleave={(e: any) => {
- e.stopPropagation();
- e.preventDefault();
- if (isTouch) return;
- cancelNotePress(point.children);
- }}
- onTouchstart={(e: any) => {
- e.stopPropagation();
- e.preventDefault();
- isTouch = true;
- startNotePress(point.children);
- }}
- onTouchend={(e: any) => {
- e.stopPropagation();
- e.preventDefault();
- cancelNotePress(point.children);
- }}
- onTouchcancel={(e: any) => {
- e.stopPropagation();
- e.preventDefault();
- cancelNotePress(point.children);
- }}
- style={point.children.style}
- ></div>
- )}
- </div>
- ))}
- </div>
- </div>
- )}
- </div>
- </div>
- </div>
- {/* 老师端过来隐藏 */}
- {query.platform === "pc" ? (
- <div class={[styles.userTab, data.domOverlapping && data.notePoints?.length > 0 && styles.usrTabOverlaping]} id="fullInstrumentUserTab">
- <Tabs v-model:active={userTabActive.value} class={styles.userTabBox}>
- {userTabs.map((item) => {
- return (
- <Tab title={item.name} name={item.value}>
- {item.value === "1" ? (
- <>
- <div
- class={styles.notes}
- style={{
- paddingLeft: data.paddingLeft ? data.paddingLeft : "",
- }}
- >
- {playAction.listenTipsStatus && <div class={[styles.tipsT, data.fingeringMode === "fingeringMode" ? styles.playTips2 : styles.playTips]}></div>}
- {playAction.userAnswerStatus === 1 && <div class={[styles.tipsT, styles.playSuccess]}></div>}
- {playAction.userAnswerStatus === 2 && <div class={[styles.tipsT, styles.playError]}></div>}
- {playAction.resetAction && <div class={[styles.tipsT, styles.playTips5]}></div>}
- <div class={[styles.backBtn, styles.changeMusBtn]} onClick={() => handleBack()}>
- <span>返回</span>
- </div>
- <div class={styles.changeMusBtn} onClick={onChangeFingeringModel}>
- <span>{modeText.value.text}</span>
- </div>
- <div
- class={[styles.noteContent, data.fingeringMode !== "scaleMode" && orientationDirection.value === 0 && styles.noteContentOther, browsInfo.ios ? "" : styles.noteContentWrap, data.huaweiPad && styles.huaweiPad]}
- onClick={(e: any) => {
- e.stopPropagation();
- }}
- >
- {((data.noteType !== "#c" && (orientationDirection.value === 0 || (orientationDirection.value === 1 && state.platform === IPlatform.PC))) || (orientationDirection.value === 1 && state.platform === IPlatform.APP)) && (
- <Button
- class={styles.noteBtn}
- onClick={(e: any) => {
- e.stopPropagation();
- scrollNoteBox("left");
- }}
- >
- <Icon name="arrow-left" />
- </Button>
- )}
- {/* 判断是否为音阶模式 */}
- {data.fingeringMode !== "scaleMode" && (
- <div draggable={false} class={styles.note} onClick={noteChangeShow}>
- <img draggable={false} src={data.noteType === "all" ? icons.icon_btn_orange : icons.icon_btn_orange2} />
- </div>
- )}
- {!!data.tones.length && data.fingeringMode === "scaleMode" && (
- <>
- {fingerData.fingeringInfo.name == "hulusi-flute" ? (
- <div id="finger-note-1" class={[styles.note, styles.btnGrToggleBtn]} onClick={() => (data.tnoteShow = true)}>
- <img draggable={false} src={noteImg} />
- <div class={styles.nameBox}>
- <div class={styles.name}>全按作</div>
- <div class={[styles.noteKey, styles.noteKeyBtn]}>
- {data.activeTone.step > 0 ? <span class={styles.dot}></span> : null}
- <div class={styles.noteName}>
- <sup>{data.activeTone.mark && (data.activeTone.mark === "rise" ? "#" : "b")}</sup>
- {data.activeTone.key}
- </div>
- {data.activeTone.step < 0 ? <span class={[styles.dot, styles.botDot]}></span> : null}
- </div>
- </div>
- </div>
- ) : (
- <div id="finger-note-1" class={[styles.note, styles.btnGrToggleBtn]} onClick={() => (data.tnoteShow = true)}>
- <img draggable={false} src={noteImg} />
- <div>
- <div class={styles.name}>
- <div>
- <sup>{data.activeTone.mark && (data.activeTone.mark === "rise" ? "#" : "b")}</sup>
- {data.activeTone.name}
- </div>
- 调
- </div>
- </div>
- </div>
- )}
- </>
- )}
- {/* [styles.noteContent, browsInfo.ios ? "" : styles.noteContentWrap, data.huaweiPad && styles.huaweiPad] */}
- <div class={styles.lastNoteContent}>
- <div ref={noteBoxRef} class={styles.noteBox}>
- {data.notes.map((note: IFIGNER_INSTRUMENT_Note, index: number) => {
- const steps = new Array(Math.abs(note.step)).fill(1);
- return (
- <div
- id={index == 0 ? "finger-note-0" : ""}
- draggable={false}
- class={[styles.note, "note-class"]}
- key={note.realKey}
- // onClick={async () => {
- // noteInstrumentPlay(note);
- // }}
- onMousedown={(e: any) => {
- e.stopPropagation();
- e.preventDefault();
- if (isTouch) return;
- startNotePress(note, false);
- }}
- onMouseup={(e: any) => {
- e.stopPropagation();
- e.preventDefault();
- if (isTouch) return;
- cancelNotePress(note, false);
- }}
- onMouseleave={(e: any) => {
- e.stopPropagation();
- e.preventDefault();
- if (isTouch) return;
- cancelNotePress(note, false);
- }}
- onTouchstart={(e: any) => {
- e.stopPropagation();
- e.preventDefault();
- isTouch = true;
- startNotePress(note, false);
- }}
- onTouchend={(e: any) => {
- e.stopPropagation();
- e.preventDefault();
- cancelNotePress(note, false);
- }}
- onTouchcancel={(e: any) => {
- e.stopPropagation();
- e.preventDefault();
- cancelNotePress(note, false);
- }}
- >
- <img draggable={false} src={resultImg(note).icon} />
- {playStatus.action && ((playAction.showAnswerLoading && playAction.standardAnswer.realKey === note.realKey) || (playAction.userAnswerStatus === 1 && playAction.userAnswer.realKey === note.realKey)) ? <span class={styles.showAnswer}></span> : ""}
- {playStatus.action && playAction.userAnswerStatus === 2 && playAction.userAnswer.realKey === note.realKey ? <span class={[styles.showAnswer, styles.errorAnswer]}></span> : ""}
- <div
- class={[
- styles.noteKey,
- ((data.realKey === note.realKey && !playStatus.action) ||
- (playStatus.action && playAction.exampleAnser.realKey === note.realKey) ||
- (playStatus.action && ((playAction.showAnswerLoading && playAction.standardAnswer.realKey === note.realKey) || (playAction.userAnswerStatus === 1 && playAction.userAnswer.realKey === note.realKey))) ||
- (playStatus.action && playAction.userAnswerStatus === 2 && playAction.userAnswer.realKey === note.realKey)) &&
- styles.keyActive,
- ]}
- >
- {/* 显示对应的点 */}
- {note.step > 0 ? steps.map((n: any) => <span class={styles.dot}></span>) : null}
- <div class={styles.noteName}>
- <sup>{note.mark && (note.mark === "rise" ? "#" : "b")}</sup>
- {note.key}
- </div>
- {/* 显示对应的点 */}
- {note.step < 0 ? steps.map((n: any) => <span class={styles.dot}></span>) : null}
- </div>
- </div>
- );
- })}
- </div>
- </div>
- {((data.noteType !== "#c" && (orientationDirection.value === 0 || (orientationDirection.value === 1 && state.platform === IPlatform.PC))) || (orientationDirection.value === 1 && state.platform === IPlatform.APP)) && (
- <Button
- class={styles.noteBtn}
- onClick={(e: any) => {
- e.stopPropagation();
- scrollNoteBox("right");
- }}
- >
- <Icon name="arrow" />
- </Button>
- )}
- </div>
- <div class={styles.restoreBox}>
- {instrumentTranstion.value && (
- <div class={[styles.restoreBtn]} onClick={() => resetElement()}>
- </div>
- )}
- </div>
- <div class={styles.moreFun}>
- 更多功能
- <div class={styles.btnBox}>
- <div class={styles.btnCon}>
- <div
- class={[styles.btnGr]}
- onClick={(e) => {
- e.stopPropagation();
- //
- // 播放音阶时不能切换
- if (playStatus.gamut) {
- return;
- }
- // 开始答题不能切换
- if (playAction.listenLock) {
- return;
- }
- data.changeSubjectShow = true;
- }}
- >
- <img src={icons.icon_change_instrument} />
- <span>切换乐器</span>
- </div>
- {data.subject !== "melodica" && data.fingeringMode === "scaleMode" && (
- <div
- class={styles.btnGr}
- onClick={(e) => {
- e.stopPropagation();
- data.viewIndex++;
- if (data.viewIndex > data.viewTotal) {
- if (["pan-flute", "ocarina", "whistling"].includes(data.subject)) {
- data.viewIndex = 1;
- } else {
- data.viewIndex = 0;
- }
- }
- getFingeringData();
- }}
- >
- <img src={icons.icon_toggle} />
- <span>视图</span>
- </div>
- )}
- <div
- class={styles.btnGr}
- onClick={(e) => {
- e.stopPropagation();
- resetElement();
- data.tipShow = !data.tipShow;
- onResize();
- }}
- >
- <img src={icons.icon_2_1} />
- <span>说明</span>
- </div>
- <div class={styles.triangle}></div>
- </div>
- </div>
- </div>
- </div>
- {data.fingeringMode !== "scaleMode" && (
- <div
- class={styles.optionBtns}
- onClick={(e: any) => {
- e.stopPropagation();
- }}
- >
- <Button class={[styles.oBtn, styles.gamut, playStatus.action && styles.disabled]} round onClick={onGamutPlayOrPause}>
- {playStatus.gamut ? "暂停" : "播放音阶"}
- </Button>
- <Button class={[styles.oBtn, styles.play, playStatus.gamut && styles.disabled]} round onClick={onActionPlay}>
- {listenText.value}
- </Button>
- <Button class={[styles.oBtn, styles.success, !playStatus.answer && styles.disabled]} round onClick={onShowAnswer}>
- 显示答案
- </Button>
- </div>
- )}
- </>
- ) : (
- <>
- {/* <div class={styles.btnBox}>
- <div class={styles.btnCon}>
- <div
- class={[styles.btnGr]}
- onClick={(e) => {
- e.stopPropagation();
- //
- // 播放音阶时不能切换
- if (playStatus.gamut) {
- return;
- }
- // 开始答题不能切换
- if (playAction.listenLock) {
- return;
- }
- data.changeSubjectShow = true;
- }}
- >
- <img src={icons.icon_change_instrument} />
- <span>切换乐器</span>
- </div>
- {data.subject !== "melodica" && data.fingeringMode === "scaleMode" && (
- <div
- class={styles.btnGr}
- onClick={() => {
- data.viewIndex++;
- if (data.viewIndex > data.viewTotal) {
- if (["pan-flute", "ocarina", "whistling"].includes(data.subject)) {
- data.viewIndex = 1;
- } else {
- data.viewIndex = 0;
- }
- }
- getFingeringData();
- }}
- >
- <img src={icons.icon_toggle} />
- <span>视图</span>
- </div>
- )}
- <div
- class={styles.btnGr}
- onClick={() => {
- resetElement();
- data.tipShow = !data.tipShow;
- onResize();
- }}
- >
- <img src={icons.icon_2_1} />
- <span>说明</span>
- </div>
- {instrumentTranstion.value && (
- <div class={[styles.btnGr]} onClick={() => resetElement()}>
- <img src={icons.icon_2_0} />
- <span>还原</span>
- </div>
- )}
- </div>
- </div> */}
- </>
- )}
- </Tab>
- );
- })}
- </Tabs>
- </div>
- ) : (
- <div class={[data.domOverlapping && data.notePoints?.length > 0 && styles.usrTabOverlapingNotes]} id="fullInstrumentUserTab">
- <div
- class={[styles.notes]}
- style={{
- paddingLeft: data.paddingLeft ? data.paddingLeft : "",
- }}
- >
- {playAction.listenTipsStatus && <div class={[styles.tipsT, data.fingeringMode === "fingeringMode" ? styles.playTips2 : styles.playTips]}></div>}
- {playAction.userAnswerStatus === 1 && <div class={[styles.tipsT, styles.playSuccess]}></div>}
- {playAction.userAnswerStatus === 2 && <div class={[styles.tipsT, styles.playError]}></div>}
- {playAction.resetAction && <div class={[styles.tipsT, styles.playTips5]}></div>}
- {((data.noteType !== "#c" && (orientationDirection.value === 0 || (orientationDirection.value === 1 && state.platform === IPlatform.PC))) || (orientationDirection.value === 1 && state.platform === IPlatform.APP)) && (
- <Button
- class={styles.noteBtn}
- onClick={(e: any) => {
- e.stopPropagation();
- scrollNoteBox("left");
- }}
- >
- <Icon name="arrow-left" />
- </Button>
- )}
- <div
- class={[styles.noteContent, data.fingeringMode !== "scaleMode" && orientationDirection.value === 0 && styles.noteContentOther, browsInfo.ios ? "" : styles.noteContentWrap, data.huaweiPad && styles.huaweiPad]}
- onClick={(e: any) => {
- e.stopPropagation();
- }}
- >
- {/* 判断是否为音阶模式 */}
- {data.fingeringMode !== "scaleMode" && (
- <div draggable={false} class={styles.note} onClick={noteChangeShow}>
- <img draggable={false} src={data.noteType === "all" ? icons.icon_btn_orange : icons.icon_btn_orange2} />
- </div>
- )}
- {/* [styles.noteContent, browsInfo.ios ? "" : styles.noteContentWrap, data.huaweiPad && styles.huaweiPad] */}
- <div class={styles.lastNoteContent}>
- <div ref={noteBoxRef} class={styles.noteBox} id="noteBox">
- {data.notes.map((note: IFIGNER_INSTRUMENT_Note, index: number) => {
- const steps = new Array(Math.abs(note.step)).fill(1);
- return (
- <div
- id={index == 0 ? "finger-note-0" : ""}
- draggable={false}
- class={[styles.note, "note-class"]}
- key={note.realKey}
- // onClick={async () => {
- // noteInstrumentPlay(note);
- // }}
- onMousedown={(e: any) => {
- e.stopPropagation();
- e.preventDefault();
- if (isTouch) return;
- startNotePress(note, false);
- }}
- onMouseup={(e: any) => {
- e.stopPropagation();
- e.preventDefault();
- if (isTouch) return;
- cancelNotePress(note, false);
- }}
- onMouseleave={(e: any) => {
- e.stopPropagation();
- e.preventDefault();
- if (isTouch) return;
- cancelNotePress(note, false);
- }}
- onTouchstart={(e: any) => {
- e.stopPropagation();
- e.preventDefault();
- isTouch = true;
- startNotePress(note, false);
- }}
- onTouchend={(e: any) => {
- e.stopPropagation();
- e.preventDefault();
- cancelNotePress(note, false);
- }}
- onTouchcancel={(e: any) => {
- e.stopPropagation();
- e.preventDefault();
- cancelNotePress(note, false);
- }}
- >
- <img draggable={false} src={resultImg(note).icon} />
- {playStatus.action && ((playAction.showAnswerLoading && playAction.standardAnswer.realKey === note.realKey) || (playAction.userAnswerStatus === 1 && playAction.userAnswer.realKey === note.realKey)) ? <span class={styles.showAnswer}></span> : ""}
- {playStatus.action && playAction.userAnswerStatus === 2 && playAction.userAnswer.realKey === note.realKey ? <span class={[styles.showAnswer, styles.errorAnswer]}></span> : ""}
- <div
- class={[
- styles.noteKey,
- ((data.realKey === note.realKey && !playStatus.action) ||
- (playStatus.action && playAction.exampleAnser.realKey === note.realKey) ||
- (playStatus.action && ((playAction.showAnswerLoading && playAction.standardAnswer.realKey === note.realKey) || (playAction.userAnswerStatus === 1 && playAction.userAnswer.realKey === note.realKey))) ||
- (playStatus.action && playAction.userAnswerStatus === 2 && playAction.userAnswer.realKey === note.realKey)) &&
- styles.keyActive,
- ]}
- >
- {/* 显示对应的点 */}
- {note.step > 0 ? steps.map((n: any) => <span class={styles.dot}></span>) : null}
- <div class={styles.noteName}>
- <sup>{note.mark && (note.mark === "rise" ? "#" : "b")}</sup>
- {note.key}
- </div>
- {/* 显示对应的点 */}
- {note.step < 0 ? steps.map((n: any) => <span class={styles.dot}></span>) : null}
- </div>
- </div>
- );
- })}
- </div>
- </div>
- </div>
- {((data.noteType !== "#c" && (orientationDirection.value === 0 || (orientationDirection.value === 1 && state.platform === IPlatform.PC))) || (orientationDirection.value === 1 && state.platform === IPlatform.APP)) && (
- <Button
- class={styles.noteBtn}
- onClick={(e: any) => {
- e.stopPropagation();
- scrollNoteBox("right");
- }}
- >
- <Icon name="arrow" />
- </Button>
- )}
- </div>
- {data.fingeringMode !== "scaleMode" && (
- <div
- class={styles.optionBtns}
- onClick={(e: any) => {
- e.stopPropagation();
- }}
- >
- <Button class={[styles.oBtn, styles.gamut, playStatus.action && styles.disabled]} round onClick={onGamutPlayOrPause}>
- {playStatus.gamut ? "暂停" : "播放音阶"}
- </Button>
- <Button class={[styles.oBtn, styles.play, playStatus.gamut && styles.disabled]} round onClick={onActionPlay}>
- {listenText.value}
- </Button>
- <Button class={[styles.oBtn, styles.success, !playStatus.answer && styles.disabled]} round onClick={onShowAnswer}>
- 显示答案
- </Button>
- </div>
- )}
- </div>
- )}
- </div>
- {/* 老师端过来隐藏 */}
- {query.platform !== "pc" && (
- <div
- class={styles.fixedRightBtns}
- style={{
- paddingTop: data.paddingTop ? data.paddingTop : "",
- paddingLeft: data.paddingLeft ? data.paddingLeft : "",
- }}
- onClick={(e: any) => {
- e.stopPropagation();
- }}
- >
- <div class={styles.rightBtn}>
- {data.subject !== "melodica" && data.fingeringMode === "scaleMode" && (
- <div
- class={styles.baseBtn}
- onClick={() => {
- data.viewIndex++;
- if (data.viewIndex > data.viewTotal) {
- if (["pan-flute", "ocarina", "whistling"].includes(data.subject)) {
- data.viewIndex = 1;
- } else {
- data.viewIndex = 0;
- }
- }
- getFingeringData();
- }}
- >
- <img src={icons.icon_toggle} />
- <span>视图</span>
- </div>
- )}
- <div
- class={styles.baseBtn}
- onClick={() => {
- resetElement();
- data.tipShow = !data.tipShow;
- onResize();
- }}
- >
- <img src={icons.icon_2_1} />
- <span>说明</span>
- </div>
- {!!data.tones.length && data.fingeringMode === "scaleMode" && (
- <>
- {fingerData.fingeringInfo.name == "hulusi-flute" ? (
- <div id="finger-note-1" class={[styles.baseBtn, styles.toggleBtnhulusi, styles.active]} onClick={() => (data.tnoteShow = true)}>
- <div>
- 全按作
- <div class={[styles.noteKey, styles.noteKeyBtn]}>
- {data.activeTone.step > 0 ? <span class={[styles.topDot, styles.dot]}></span> : null}
- <div class={styles.noteName}>
- <sup>{data.activeTone.mark && (data.activeTone.mark === "rise" ? "#" : "b")}</sup>
- {data.activeTone.key}
- </div>
- {data.activeTone.step < 0 ? <span class={[styles.bottomDot, styles.dot]}></span> : null}
- </div>
- </div>
- <img src={icons.icon_arrow} />
- </div>
- ) : (
- <div id="finger-note-1" class={[styles.baseBtn, styles.toggleBtnhulusi2, styles.active]} onClick={() => (data.tnoteShow = true)}>
- <div class={styles.oterhD}>
- <div>
- <div style={{ marginTop: "-4px" }}>
- <sup>{data.activeTone.mark && (data.activeTone.mark === "rise" ? "#" : "b")}</sup>
- {data.activeTone.name}
- </div>
- 调
- </div>
- <img src={icons.icon_arrow} />
- </div>
- </div>
- )}
- </>
- )}
- </div>
- <div class={[styles.baseBtn, !instrumentTranstion.value && styles.resetBtn]} style={{ marginTop: "8px" }} onClick={() => resetElement()}>
- <img src={icons.icon_2_0} />
- <span>还原</span>
- </div>
- </div>
- )}
- {/* 老师端加上遮罩点击关闭 */}
- {query.platform === "pc" && data.tipShow && (
- <div
- class={[styles.tipsOverlay, data.tipShow ? styles.tipsOverlayBg : ""]}
- onClick={() => {
- data.tipShow = false;
- }}
- ></div>
- )}
- <div class={[styles.tips, data.loadingDom ? styles.hiddens : "", data.tipShow ? "" : styles.tipHidden, query.platform === "pc" && data.tipShow ? styles.tipsPcBg : ""]}>
- <div class={styles.tipTitle}>
- <div class={styles.tipTitleName}>{fingerData.fingeringInfo.code}使用说明</div>
- <Button
- class={styles.tipClose}
- onClick={(e: any) => {
- e.stopPropagation();
- data.tipShow = false;
- }}
- >
- <Icon name="cross" size={19} color="#fff" />
- </Button>
- </div>
- <div class={styles.iconBook}></div>
- <div class={styles.tipContentbox}>
- <div class={styles.tipContent}>
- {data.tips.map((tip, tipIndex) => (
- <div class={styles.tipItem}>
- <div class={styles.iconWrap}>
- <div class={styles.tipItemIcon}>{tipIndex + 1}</div>
- </div>
- <div>
- {tip.name}: {tip.realName}
- </div>
- </div>
- ))}
- </div>
- </div>
- </div>
- {data.loadingSoundFonts && (
- <div class={styles.loading}>
- <div class={styles.loadingWrap}>
- <img class={styles.loadingIcon} src={icon_loading_img} />
- <Progress percentage={data.loadingSoundProgress} />
- <div class={styles.loadingTip}>加载中,请稍后…</div>
- </div>
- </div>
- )}
- </div>
- <Popup
- class={["tonePopup", tnoteShowBoxClass]}
- style={query.platform === "pc" ? tnoteShowBoxDragData.styleDrag.value : {}}
- v-model:show={data.tnoteShow}
- position={state.platform === IPlatform.PC ? "center" : !query.modelType && fingerData.fingeringInfo.orientation === 1 ? "bottom" : "right"}
- >
- <div class={styles.tones}>
- <div class={[styles.toneTitle, "toneTitle_pc"]}>
- <div class={styles.tipTitleName}>移调</div>
- <Button
- class={styles.tipClose}
- onClick={(e: any) => {
- e.stopPropagation();
- data.tnoteShow = false;
- }}
- >
- <Icon name="cross" size={19} color="#fff" />
- </Button>
- </div>
- <div class={[styles.tipContentbox, "tipContentbox_pc"]}>
- <div class={[styles.tipContent, "tipContent_pc"]}>
- <div class={[styles.tipWrap, "tipWrap_pc"]}>
- <Space size={0} class={styles.toneContent}>
- {data.tones.map((tone: IFIGNER_INSTRUMENT_Note) => {
- const steps = new Array(Math.abs(tone.step)).fill(1);
- return (
- <Button
- class={[fingerData.fingeringInfo.name == "hulusi-flute" && styles.hulusiBtn]}
- round
- plain
- type={data.popupActiveTone.realName === tone.realName ? "primary" : "default"}
- onClick={(e: any) => {
- e.stopPropagation();
- data.popupActiveTone = tone;
- setNotes();
- }}
- >
- {fingerData.fingeringInfo.name == "hulusi-flute" ? (
- <div style={{ display: "flex", alignItems: "center" }}>
- 全按作
- <div class={[styles.noteKey, styles.hulusiNoteKey]}>
- {tone.step > 0 ? <span class={styles.dot}></span> : null}
- <div class={styles.noteName} style={{ fontSize: "0.25rem" }}>
- <sup>{tone.mark && (tone.mark === "rise" ? "#" : "b")}</sup>
- {tone.key}
- </div>
- {tone.step < 0 ? <span class={styles.dot}></span> : null}
- </div>
- </div>
- ) : (
- <div class={styles.noteName}>
- <sup>{tone.mark && (tone.mark === "rise" ? "#" : "b")}</sup>
- {tone.name}
- </div>
- )}
- </Button>
- );
- })}
- </Space>
- </div>
- <div class={[styles.toneAction, "toneAction_pc"]}>
- <img
- onClick={(e: any) => {
- e.stopPropagation();
- data.tnoteShow = false;
- }}
- src={icons.icon_action_cancel}
- />
- <img
- onClick={(e: any) => {
- e.stopPropagation();
- data.activeTone = data.popupActiveTone;
- setNotes();
- data.tnoteShow = false;
- }}
- src={icons.icon_action_confirm}
- />
- </div>
- </div>
- </div>
- </div>
- {query.platform === "pc" && (
- <>
- <div class={[styles.dragTopBox, "dragTopBox"]}></div>
- <Dragbom showGuide={guidanceShow.value} onGuideDone={setGuidanceShow}></Dragbom>
- </>
- )}
- </Popup>
- <Popup
- style={query.platform === "pc" ? changeSubjectShowBoxDragData.styleDrag.value : {}}
- v-model:show={data.changeSubjectShow}
- class={[styles.changeSubjectPopup, query.platform === "pc" && styles.changeSubjectPopupPc, changeSubjectShowBoxClass]}
- closeOnClickOverlay={query.platform === "pc" ? false : true}
- onClick={(e: any) => {
- e.stopPropagation();
- }}
- >
- <ChangeSubject
- changeSubjectShow={data.changeSubjectShow}
- subjectList={data.subjects}
- subject={data.subject}
- onClose={() => (data.changeSubjectShow = false)}
- onConfirm={(code: any) => {
- if (data.subject === code) {
- data.changeSubjectShow = false;
- return;
- }
- const originalSubject = JSON.parse(JSON.stringify(data.subject));
- data.subject = code;
- data.viewIndex = 0;
- data.tipShow = false;
- data.loadingDom = true;
- fingerData.fingeringInfo = subjectFingering(data.subject);
- data.activeTone = {} as any;
- data.noteType = "all";
- resetElement();
- resetMode(true, 0);
- // api_setRequestedOrientation(orientationDirection.value);
- data.changeSubjectShow = false;
- // 设置屏幕方向
- setTimeout(() => {
- const before = ["hulusi-flute", "piccolo", "baroque-recorder"].includes(originalSubject) ? 0 : 0;
- if (orientationDirection.value !== before) {
- data.paddingTop = "";
- data.paddingLeft = "";
- }
- __init();
- }, 100);
- }}
- />
- {query.platform === "pc" && (
- <>
- <div class={[styles.dragTopBox, "dragTopBox"]}></div>
- <Dragbom showGuide={guidanceShow.value} onGuideDone={setGuidanceShow}></Dragbom>
- </>
- )}
- </Popup>
- {props.show && !data.loading && !data.loadingSoundFonts && <GuideIndex fingeringMode={data.fingeringMode} showGuide={false} list={["finger"]} />}
- </div>
- );
- };
- },
- });
|