123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 |
- 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 () => (
- <div
- id="selectionBox"
- class={styles.selectionContainer}
- onClick={(e: Event) => e.stopPropagation()}
- >
- {selectData.staves.map((item: any) => {
- const scoreItem = item.id && evaluatingData.evaluatings[item.measureListIndex];
- // 高级模式下,显示节拍线
- // 不是报告模式
- // 不是多小节休止符
- // 节拍线开关
- // 当前小节
- // 当前小节
- const lineShow =
- !state.isReport &&
- !state.times[state.activeNoteIndex].multipleRestMeasures &&
- metronomeData.cursorMode === 2 &&
- item.MeasureNumberXML === metronomeData.activeMetro?.measureNumberXML &&
- state.times[state.activeNoteIndex].MeasureNumberXML === item.MeasureNumberXML;
- return (
- <>
- {item.staveBox && (
- <div
- class={[
- styles.position,
- showClass.value(item),
- scoreItem ? `scoreItemLeve${scoreItem.leve}` : "",
- state.platform === IPlatform.PC ? styles.linePC : ''
- ]}
- style={item.staveBox}
- onClick={() => handleSelection(item)}
- >
- {lineShow && (
- <div
- class={[
- styles.line,
- state.musicRenderType == EnumMusicRenderType.staff ? styles.lineStaff : styles.lineJianPu,
- ]}
- style={{ left: metronomeData.activeMetro.left }}></div>
- )}
- {!state.isReport &&
- !!item.multipleRestMeasures &&
- state.activeMeasureIndex == item.MeasureNumberXML && (
- <div class={styles.dotWrap}>{item.multipleRestMeasures}</div>
- )}
- <Transition
- name="centerTop"
- onAfterEnter={() => {
- scoreItem.show = false;
- }}
- >
- {scoreItem?.show && (
- <div
- class={styles.scoreItem}
- style={{ color: leveByScoreMeasureIcons[scoreItem.leve]?.color || "" }}
- >
- <img src={leveByScoreMeasureIcons[scoreItem.leve]?.icon} />
- <span>{scoreItem.score}</span>
- </div>
- )}
- </Transition>
- </div>
- )}
- </>
- );
- })}
- {selectData.notes.map((item: any) => {
- return (
- <div
- class={[styles.position, disableClickNote.value && styles.disable, styles.note, `noteIndex_${item.index}`]}
- style={item.bbox}
- onClick={() => skipNotePlay(item.index)}
- >
- <div class={styles.noteFollow} data-vf={"vf" + item.id}>
- <Icon name="success" />
- <Icon name="cross" />
- </div>
- </div>
- );
- })}
- {/* 移动模块 */}
- {/* {query.isMove == "1" && <MoveMusicScore />} */}
- </div>
- );
- },
- });
|