|
@@ -22,6 +22,7 @@ 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",
|
|
@@ -51,6 +52,7 @@ export default defineComponent({
|
|
|
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,
|
|
@@ -102,6 +104,11 @@ export default defineComponent({
|
|
|
noteType: "all" as "#c" | "all", // 音调
|
|
|
loadingDom: false, // 切换乐器时需要重置
|
|
|
loadingImg: false, // 切换模式,加载图片
|
|
|
+ domOverlapping: false, // 元素是否被遮住
|
|
|
+ domOverImgPropery: {
|
|
|
+ width: "100%",
|
|
|
+ height: "100%",
|
|
|
+ } as any,
|
|
|
});
|
|
|
const fingerData = reactive({
|
|
|
relationshipIndex: 0,
|
|
@@ -166,6 +173,7 @@ export default defineComponent({
|
|
|
// 判断是音符状态
|
|
|
data.notes = data.noteType === "#c" ? appendNote : tempNotes;
|
|
|
// data.notes = fignerData[`list${data.activeTone.realName || ""}`];
|
|
|
+ data.notePoints = FINER_INSTRUMENT_POINT[data.subject];
|
|
|
}
|
|
|
};
|
|
|
const getFingeringData = async () => {
|
|
@@ -251,6 +259,7 @@ export default defineComponent({
|
|
|
data.noteType = "all";
|
|
|
}
|
|
|
data.tipShow = false;
|
|
|
+ resetElement();
|
|
|
resetMode(true, 0);
|
|
|
setTimeout(() => {
|
|
|
__init(false);
|
|
@@ -291,6 +300,9 @@ export default defineComponent({
|
|
|
|
|
|
data.loadingDom = false;
|
|
|
data.loadingImg = false;
|
|
|
+
|
|
|
+ // 初始化获取元素宽高
|
|
|
+ onResize();
|
|
|
};
|
|
|
|
|
|
// 获取声部
|
|
@@ -383,13 +395,17 @@ export default defineComponent({
|
|
|
__init();
|
|
|
});
|
|
|
|
|
|
+ // 播放时间
|
|
|
+ let noteTimer: any = null;
|
|
|
/**
|
|
|
* 播放音频
|
|
|
* @param item 音频节点
|
|
|
* @param showNote 是否显示对应的指法
|
|
|
+ * @param isScrollShowNote 是否滚动到对应播放的位置
|
|
|
+ * @param autoStop 是否自动停止
|
|
|
* @returns
|
|
|
*/
|
|
|
- const noteClick = (item: IFIGNER_INSTRUMENT_Note, showNote = true) => {
|
|
|
+ const noteClick = (item: IFIGNER_INSTRUMENT_Note, showNote = true, isScrollShowNote = false, autoStop = false, callBack?: any) => {
|
|
|
// console.log('音高', item.realKey)
|
|
|
if (data.noteAudio) {
|
|
|
data.noteAudio.stop();
|
|
@@ -398,14 +414,27 @@ export default defineComponent({
|
|
|
data.noteAudio = null as unknown as Howl;
|
|
|
return;
|
|
|
}
|
|
|
+
|
|
|
+ clearTimeout(noteTimer);
|
|
|
}
|
|
|
if (showNote) {
|
|
|
data.realKey = item.realKey;
|
|
|
}
|
|
|
- console.log("key:", item.realKey, data.soundFonts);
|
|
|
+ // 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 = () => {
|
|
@@ -416,6 +445,106 @@ export default defineComponent({
|
|
|
}
|
|
|
};
|
|
|
|
|
|
+ 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,
|
|
@@ -465,6 +594,16 @@ export default defineComponent({
|
|
|
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();
|
|
@@ -472,9 +611,12 @@ export default defineComponent({
|
|
|
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")]);
|
|
|
- // mc.get("pan").set({ direction: Hammer.DIRECTION_ALL });
|
|
|
- // mc.get("pinch").set({ enable: true });
|
|
|
+
|
|
|
+ let dragTimeout: any;
|
|
|
+
|
|
|
mc.on("panstart pinchstart", function (ev) {
|
|
|
+ isDragging.value = true;
|
|
|
+ clearTimeout(dragTimeout);
|
|
|
data.transform.transition = "";
|
|
|
});
|
|
|
mc.on("panmove pinchmove", function (ev) {
|
|
@@ -483,19 +625,40 @@ export default defineComponent({
|
|
|
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);
|
|
|
}
|
|
|
});
|
|
|
};
|
|
@@ -508,6 +671,7 @@ export default defineComponent({
|
|
|
data.transform.startScale = data.subject === "pan-flute" ? 0.9 : 1;
|
|
|
data.transform.startX = 0;
|
|
|
data.transform.startY = 0;
|
|
|
+ data.domOverlapping = false;
|
|
|
});
|
|
|
};
|
|
|
|
|
@@ -541,6 +705,14 @@ export default defineComponent({
|
|
|
}
|
|
|
}
|
|
|
);
|
|
|
+ watch(
|
|
|
+ () => data.tipShow,
|
|
|
+ (val: any) => {
|
|
|
+ if (!val) {
|
|
|
+ onResize();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ );
|
|
|
/** 课件播放 */
|
|
|
const changePlay = (res: any) => {
|
|
|
if (res?.data?.api === "setPlayState") {
|
|
@@ -571,7 +743,38 @@ export default defineComponent({
|
|
|
|
|
|
const noteBoxRef = ref();
|
|
|
const scrollNoteBox = (type: "left" | "right") => {
|
|
|
- const width = noteBoxRef.value.offsetWidth / 2;
|
|
|
+ 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",
|
|
@@ -606,6 +809,13 @@ export default defineComponent({
|
|
|
getNotes();
|
|
|
|
|
|
setTimeout(() => {
|
|
|
+ (noteBoxRef.value as unknown as HTMLElement).scroll({
|
|
|
+ left: 0,
|
|
|
+ top: 0,
|
|
|
+ behavior: "smooth",
|
|
|
+ });
|
|
|
+ }, 0);
|
|
|
+ setTimeout(() => {
|
|
|
playAction.resetAction = false;
|
|
|
}, 2000);
|
|
|
};
|
|
@@ -801,6 +1011,7 @@ export default defineComponent({
|
|
|
};
|
|
|
|
|
|
/** 滚轮缩放 */
|
|
|
+
|
|
|
const handleWheel = (e: WheelEvent) => {
|
|
|
e.preventDefault();
|
|
|
if (e.deltaY > 0) {
|
|
@@ -814,16 +1025,39 @@ export default defineComponent({
|
|
|
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);
|
|
|
});
|
|
|
|
|
|
onUnmounted(() => {
|
|
|
window.removeEventListener("message", changePlay);
|
|
|
+ window.removeEventListener("resize", onResize);
|
|
|
const fingeringContainer = document.getElementById("fingeringContainer");
|
|
|
fingeringContainer?.removeEventListener("wheel", handleWheel);
|
|
|
document.title = "Ai学练";
|
|
@@ -1085,7 +1319,7 @@ export default defineComponent({
|
|
|
<div class={styles.wrapFinger}>
|
|
|
<div
|
|
|
id="fingeringContainer"
|
|
|
- class={[styles.boxFinger, query.platform === "pc" ? styles.pcBoxFinger : ""]}
|
|
|
+ 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,
|
|
@@ -1099,21 +1333,132 @@ export default defineComponent({
|
|
|
class={[styles.fingeringContainer]}
|
|
|
>
|
|
|
<div class={styles.imgs}>
|
|
|
- {!data.loadingImg && <img src={data.fingeringMode === "scaleMode" ? fingerData.subject?.json?.full : fingerData.subject?.json?.full1} />}
|
|
|
+ {!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 data-index={nk} src={fingerData.subject?.json?.[nk]} />;
|
|
|
+ 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}>
|
|
|
+ <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 (
|
|
@@ -1203,33 +1548,42 @@ export default defineComponent({
|
|
|
draggable={false}
|
|
|
class={[styles.note, "note-class"]}
|
|
|
key={note.realKey}
|
|
|
- onClick={async () => {
|
|
|
- // 判断是否在播放音阶
|
|
|
- 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);
|
|
|
- }
|
|
|
+ // 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} />
|
|
@@ -1329,6 +1683,7 @@ export default defineComponent({
|
|
|
data.viewIndex = 0;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
getFingeringData();
|
|
|
}}
|
|
|
>
|
|
@@ -1341,6 +1696,7 @@ export default defineComponent({
|
|
|
onClick={() => {
|
|
|
resetElement();
|
|
|
data.tipShow = !data.tipShow;
|
|
|
+ onResize();
|
|
|
}}
|
|
|
>
|
|
|
<img src={icons.icon_2_1} />
|
|
@@ -1362,9 +1718,9 @@ export default defineComponent({
|
|
|
</Tabs>
|
|
|
</div>
|
|
|
) : (
|
|
|
- <>
|
|
|
+ <div class={[data.domOverlapping && data.notePoints?.length > 0 && styles.usrTabOverlapingNotes]} id="fullInstrumentUserTab">
|
|
|
<div
|
|
|
- class={styles.notes}
|
|
|
+ class={[styles.notes]}
|
|
|
style={{
|
|
|
paddingLeft: data.paddingLeft ? data.paddingLeft : "",
|
|
|
}}
|
|
@@ -1399,7 +1755,7 @@ export default defineComponent({
|
|
|
|
|
|
{/* [styles.noteContent, browsInfo.ios ? "" : styles.noteContentWrap, data.huaweiPad && styles.huaweiPad] */}
|
|
|
<div class={styles.lastNoteContent}>
|
|
|
- <div ref={noteBoxRef} class={styles.noteBox}>
|
|
|
+ <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 (
|
|
@@ -1408,33 +1764,42 @@ export default defineComponent({
|
|
|
draggable={false}
|
|
|
class={[styles.note, "note-class"]}
|
|
|
key={note.realKey}
|
|
|
- onClick={async () => {
|
|
|
- // 判断是否在播放音阶
|
|
|
- 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);
|
|
|
- }
|
|
|
+ // 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} />
|
|
@@ -1497,7 +1862,7 @@ export default defineComponent({
|
|
|
</Button>
|
|
|
</div>
|
|
|
)}
|
|
|
- </>
|
|
|
+ </div>
|
|
|
)}
|
|
|
</div>
|
|
|
{/* 老师端过来隐藏 */}
|
|
@@ -1537,6 +1902,7 @@ export default defineComponent({
|
|
|
onClick={() => {
|
|
|
resetElement();
|
|
|
data.tipShow = !data.tipShow;
|
|
|
+ onResize();
|
|
|
}}
|
|
|
>
|
|
|
<img src={icons.icon_2_1} />
|
|
@@ -1726,7 +2092,8 @@ export default defineComponent({
|
|
|
<Popup
|
|
|
style={query.platform === "pc" ? changeSubjectShowBoxDragData.styleDrag.value : {}}
|
|
|
v-model:show={data.changeSubjectShow}
|
|
|
- class={[styles.changeSubjectPopup, changeSubjectShowBoxClass]}
|
|
|
+ class={[styles.changeSubjectPopup, query.platform === "pc" && styles.changeSubjectPopupPc, changeSubjectShowBoxClass]}
|
|
|
+ closeOnClickOverlay={query.platform === "pc" ? false : true}
|
|
|
onClick={(e: any) => {
|
|
|
e.stopPropagation();
|
|
|
}}
|
|
@@ -1747,6 +2114,7 @@ export default defineComponent({
|
|
|
data.loadingDom = true;
|
|
|
fingerData.fingeringInfo = subjectFingering(data.subject);
|
|
|
data.activeTone = {} as any;
|
|
|
+ data.noteType = "all";
|
|
|
resetElement();
|
|
|
resetMode(true, 0);
|
|
|
// api_setRequestedOrientation(orientationDirection.value);
|