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"; import { Button, Icon, Popup, Space } from "vant"; import GuideIndex from "./guide/guide-index"; 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({ loading: true, subject: subject, realKey: 0, notes: [] as IFIGNER_INSTRUMENT_Note[], tones: [] as IFIGNER_INSTRUMENT_Note[], activeTone: {} as IFIGNER_INSTRUMENT_Note, activeToneName: "", 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: "", }, tipShow: false, tips: [] as IFIGNER_INSTRUMENT_Note[], tnoteShow: false, }); 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]; } 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) { data.notes = fignerData[`list${data.activeTone.realName || ""}`]; } }; 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()}> 还原
{ resetElement(); data.tipShow = !data.tipShow; }} > 使用说明
{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.notes.map((note: IFIGNER_INSTRUMENT_Note, index: number) => { 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}
); })}
{fingerData.fingeringInfo.code}使用说明
{data.tips.map((tip, tipIndex) => (
{tipIndex + 1}
{tip.name}: {tip.realName}
))}
{!!data.tones.length && (
(data.tnoteShow = true)}>
{data.activeTone.mark && (data.activeTone.mark === "rise" ? "#" : "b")} {data.activeTone.name}
)}
移调
{data.tones.map((tone: IFIGNER_INSTRUMENT_Note) => { const steps = new Array(Math.abs(tone.step)).fill(1); return ( ); })}
{!data.loading && }
); }; }, });