import { computed, defineComponent, onMounted, reactive, Transition } from "vue"; import state, { EnumMusicRenderType, handleSelection, skipNotePlay, IPlatform } from "/src/state"; import styles from "./index.module.less"; import { metronomeData } from "/src/helpers/metronome"; import { evaluatingData } from "../evaluating"; import { leveByScoreMeasureIcons } from "../evaluating/evaluatResult"; import { Icon } from "vant"; import MoveMusicScore from "../plugins/move-music-score"; import { useRoute } from "vue-router"; import { getQuery } from "/src/utils/queryString"; const selectData = reactive({ notes: [] as any[], staves: [] as any[], }); /** 计算点击层数据 */ const calcNoteData = () => { const musicContainer = document.getElementById("musicAndSelection")?.getBoundingClientRect() || { x: 0, y: 0, }; const parentLeft = musicContainer.x || 0; const parentTop = musicContainer.y || 0; const notes = state.times; const notesList: string[] = []; const MeasureNumberXMLList: number[] = []; for (let i = 0; i < notes.length; i++) { const item = notes[i]; // console.log("🚀 ~ item:", item) const noteItem = { ...item, index: item.i, bbox: null as any, staveBox: null as any, }; if (!notesList.includes(item.noteId)) { let staveBbox: any = {}; if (item.stave?.attrs?.id) { const staveEle = document.querySelector(`#${item.stave.attrs.id}`); staveBbox = staveEle?.parentElement?.parentElement?.getBoundingClientRect?.() || { x: 0, width: 0, }; // console.log("🚀 ~ staveBbox:", staveBbox) } if (item.svgElement) { const noteEle = document.querySelector(`#vf-${item.svgElement?.attrs?.id}`); if (noteEle) { const noteBbox = noteEle.getBoundingClientRect?.() || { x: 0, width: 0 }; if (state.musicRenderType !== EnumMusicRenderType.staff) { noteItem.bbox = { left: noteBbox.x - parentLeft - noteBbox.width / 4 + "px", top: noteBbox.y - parentTop - noteBbox.height + "px", width: noteBbox.width * 1.5 + "px", height: noteBbox.height * 3 + "px", }; const noteHead = noteEle.querySelector(".vf-numbered-note-head"); const noteHeadBbox = noteHead?.getBoundingClientRect?.(); if (noteHeadBbox) { item.bbox = { left: noteHeadBbox.x - parentLeft - noteHeadBbox.width / 4, width: noteHeadBbox.width * 1.5, } } } else { noteItem.bbox = { left: noteBbox.x - parentLeft - noteBbox.width / 4 + "px", top: staveBbox.y - parentTop + "px", width: noteBbox.width * 1.5 + "px", height: staveBbox.height + "px", }; } } selectData.notes.push(noteItem); notesList.push(item.noteId); } } if (!MeasureNumberXMLList.includes(item.MeasureNumberXML)) { if (item.stave) { if (item.stave?.attrs?.id) { const staveEle = document.querySelector(`#${item.stave.attrs.id}`); const list = [ Array.from(staveEle?.querySelectorAll(".vf-clef") || []), Array.from(staveEle?.querySelectorAll(".vf-keysignature") || []), Array.from(staveEle?.getElementsByTagName("text") || []), ].flat(); try { if (list.length) { // console.log("🚀 ~ list:", list) list.forEach((_el: any) => { _el?.style?.setProperty("display", "none"); }); } } catch (error) {} const staveBbox = staveEle?.getBoundingClientRect?.() || { x: 0, width: 0, y: 0, height: 0 }; try { if (list.length) { list.forEach((_el: any) => { _el?.style?.removeProperty("display"); }); } } catch (error) {} // console.log("🚀 ~ staveEle:", staveEle) noteItem.staveBox = { left: staveBbox.x - parentLeft + "px", // top: ((item.stave.y || 0) - 5) * state.zoom + "px", top: staveBbox.y - parentTop + "px", width: staveBbox.width + "px", height: staveBbox.height + "px", // background: 'rgba(0,0,0,.2)' }; selectData.staves.push(noteItem); } MeasureNumberXMLList.push(item.MeasureNumberXML); } else { if (item.multipleRestMeasures) { const preItem = selectData.staves.find( (n: any) => n.MeasureNumberXML === item.MeasureNumberXML - 1 ); if (preItem?.staveBox) { noteItem.staveBox = { left: preItem.staveBox.left, top: preItem.staveBox.top, width: preItem.staveBox.width, }; selectData.staves.push(noteItem); MeasureNumberXMLList.push(item.MeasureNumberXML); } } } } } // console.log("🚀 ~ selectData.notes:", selectData.staves); }; /** 重新计算 */ export const recalculateNoteData = () => { selectData.notes = []; selectData.staves = []; calcNoteData(); }; export default defineComponent({ name: "selection", setup() { const route = useRoute(); const query: any = { ...getQuery(), ...route.query, }; /** 是否可以点击音符 */ const disableClickNote = computed(() => { return state.sectionStatus || state.modeType !== "practise"; }); const showClass = computed(() => { return (item: any) => { if (state.sectionStatus) { if (state.section.length === 1) { if (item.MeasureNumberXML == state.section[0].MeasureNumberXML) { return styles.leftStaveBox; } } if (state.section.length === 2) { // 选段预备拍背景 if (state.sectionFirst && item.MeasureNumberXML === state.sectionFirst.MeasureNumberXML) { return styles.prepareStaveBox; } if ( item.MeasureNumberXML >= state.section[0].MeasureNumberXML && item.MeasureNumberXML <= state.section[1].MeasureNumberXML ) { if ( item.MeasureNumberXML == state.section[0].MeasureNumberXML && item.MeasureNumberXML == state.section[1].MeasureNumberXML ) { return styles.centerStaveBox; } if (item.MeasureNumberXML == state.section[0].MeasureNumberXML) { return styles.leftStaveBox; } if (item.MeasureNumberXML == state.section[1].MeasureNumberXML) { return styles.rightStaveBox; } return styles.staveBox; } } } else { if (state.activeMeasureIndex == item.MeasureNumberXML && !state.isReport) { return styles.staveBox; } } }; }); onMounted(() => { calcNoteData(); }); return () => (