import { PropType, computed, defineComponent, nextTick, onBeforeMount, onMounted, reactive } from "vue"; import styles from "./index.module.less"; import icons from "./image/icons.json"; import { FIGNER_INSTRUMENT_DATA, IFIGNER_INSTRUMENT_Note } from "/src/view/figner-preview"; import { ITypeFingering, IVocals, getFingeringConfig, subjectFingering, } from "/src/view/fingering/fingering-config"; import { Howl } from "howler"; import { storeData } from "/src/store"; import { api_back } from "/src/helpers/communication"; import Hammer from "hammerjs"; export default defineComponent({ name: "viewFigner", emits: ["close"], props: { isComponent: { type: Boolean, default: false, }, subject: { type: String as PropType, default: "", }, }, setup(props, { emit }) { const subject = props.subject || "pan-flute"; const data = reactive({ subject: subject, realKey: 0, notes: [] as IFIGNER_INSTRUMENT_Note[], tones: [] as IFIGNER_INSTRUMENT_Note[], activeTone: "", soundFonts: {} as any, viewIndex: 0, noteAudio: null as unknown as Howl, transform: { scale: 1, x: 0, y: 0, startScale: 1, startX: 0, startY: 0, transition: "", }, }); const fingerData = reactive({ relationshipIndex: 0, subject: null as unknown as ITypeFingering, fingeringInfo: subjectFingering(data.subject), }); 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].realName; } setNotes(); } }; const setNotes = () => { const fignerData = FIGNER_INSTRUMENT_DATA[data.subject as keyof typeof FIGNER_INSTRUMENT_DATA]; if (fignerData) { data.notes = fignerData[`list${data.activeTone}`]; } }; const getFingeringData = async () => { const subject: any = data.subject + (data.viewIndex === 0 ? "" : data.viewIndex); // console.log("πŸš€ ~ subject:", subject); fingerData.subject = await getFingeringConfig(subject); }; const getSounFonts = () => { const pathname = /(192|localhost)/.test(location.origin) ? "/" : location.pathname; 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"; const noteAudio = new Howl({ src: url, loop: true, }); data.soundFonts[note.realKey] = noteAudio; } // console.log("πŸš€ ~ data.soundFonts:", data.soundFonts); }; onBeforeMount(() => { getNotes(); getFingeringData(); getSounFonts(); }); const noteClick = (item: IFIGNER_INSTRUMENT_Note) => { if (data.noteAudio) { data.noteAudio.stop(); if (data.realKey === item.realKey) { data.realKey = 0; data.noteAudio = null as unknown as Howl; return; } } data.realKey = item.realKey; data.noteAudio = data.soundFonts[item.realKey]; data.noteAudio.play(); }; /** θΏ”ε›ž */ const handleBack = () => { if (data.noteAudio) { data.noteAudio.stop(); data.realKey = 0; data.noteAudio = null as unknown as Howl; } if (props.isComponent) { console.log("ε…³ι—­"); emit("close"); return; } // 不在APPδΈ­, if (!storeData.isApp) { window.close(); return; } api_back(); }; onMounted(() => { loadElement(); }); const loadElement = () => { const fingeringContainer = document.getElementById("fingeringContainer"); // 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")]); // mc.get("pan").set({ direction: Hammer.DIRECTION_ALL }); // mc.get("pinch").set({ enable: true }); mc.on("panstart pinchstart", function (ev) { 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; } 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; } }); // mc.on("hammer.input", function (ev) { // console.log("πŸš€ ~ ev:", ev.type, ev.isFinal); if (ev.isFinal) { data.transform.startScale = data.transform.scale; data.transform.startX = data.transform.x; data.transform.startY = data.transform.y; } }); }; const resetElement = () => { data.transform.transition = "all 0.3s"; nextTick(() => { data.transform.scale = 1; data.transform.x = 0; data.transform.y = 0; data.transform.startScale = 1; data.transform.startX = 0; data.transform.startY = 0; }); }; 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 (
{data.subject === "pan-flute" && (
{ data.viewIndex++; if (data.viewIndex > 2) { data.viewIndex = 0; } getFingeringData(); }} > εˆ‡ζ’θ§†ε›Ύ
)}
resetElement()}> 还原
ε°ζŠ€ε·§
{rs.map((key: number | string, index: number) => { const nk: string = typeof key === "string" ? key.replace("active-", "") : String(key); return ; })}
(fingerData.relationshipIndex = fingerData.relationshipIndex === 0 ? 1 : 0) } > ζ›ΏζŒ‡
{data.tones.map((tone: IFIGNER_INSTRUMENT_Note) => { const steps = new Array(Math.abs(tone.step)).fill(1); return (
{ data.activeTone = tone.realName; setNotes(); }} > {data.activeTone === tone.realName ? ( ) : ( )}
{tone.step > 0 ? steps.map((n) => ) : null}
{tone.mark && (tone.mark === "rise" ? "#" : "b")} {tone.key}
{tone.step < 0 ? steps.map((n) => ) : null}
); })}
{/* */}
{data.notes.map((note: IFIGNER_INSTRUMENT_Note) => { const steps = new Array(Math.abs(note.step)).fill(1); return (
noteClick(note)}> {data.realKey === note.realKey ? ( ) : ( )}
{note.step > 0 ? steps.map((n) => ) : null}
{note.mark && (note.mark === "rise" ? "#" : "b")} {note.key}
{note.step < 0 ? steps.map((n) => ) : null}
); })}
{/* */}
); }; }, });