1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285 |
- import { ref } from "vue";
- import state, { customData } from "../state"
- import { getQuery } from "/src/utils/queryString";
- import { setGlobalData } from "/src/utils";
- const query: any = getQuery();
- interface IItem {
- id?: string
- y?: number
- isLast?: boolean
- childIndex?: number[]
-
- }
- interface IItemList {
- parts: string[],
- tieId?: string[],
- staveSection?: IItem[],
- vfmodifiers?: IItem[],
- voltas?: number
- vfcurve?: IItem[]
- stavenote?: IItem[]
- }
- interface IMusicList {
- [_key: string]: IItemList[]
- }
- const container = ref();
- /** 曲谱配置: 重叠 */
- export const resetGivenFormate = () => {
- interface IItem {
- id?: string
- y?: number
- isLast?: boolean
- childIndex?: number[]
-
- }
- interface IItemList {
- parts: string[],
- tieId?: string[],
- staveSection?: IItem[],
- vfmodifiers?: IItem[],
- voltas?: number
- vfcurve?: IItem[]
- stavenote?: IItem[]
- }
- interface IMusicList {
- [_key: string]: IItemList[]
- }
- const musicList: IMusicList = {
- '12200': [
- {parts: ['0', '1'], tieId: ['1483']},
- {parts: ['2'], tieId: ['1463']},
- {parts: ['10'], tieId: ['1246']},
- {parts: ['11'], tieId: ['2455']},
- {parts: ['13'], tieId: ['1488', '1688']},
- {parts: ['14', '15'], tieId: ['1272']},
- {parts: ['16'], tieId: ['1264', '1368'], staveSection: [{id: 'section-0', y: -10}]},
- ],
- '12420': [
- {parts: ['0'], tieId: ['1298', '1405', '1998', '2598', '3229', '2731', '2617']}
- ],
- '7729': [
- {parts: ['3'], tieId: ['1498', '1660']}
- ],
- '7439': [
- {parts: ['23'], vfmodifiers: [{id: 'modifiers-130', y: -18, isLast: true}]}
- ],
- '12711': [
- { parts: ['0'], voltas: -12},
- { parts: ['4'],voltas: -8},
- ],
- '3581': [
- { parts: ['0'], voltas: -8},
- ],
- '6244': [
- { parts: ['15'], stavenote: [{id: 'vf-auto1608', y: -15}]},
- ],
- '7473': [
- { parts: ['0'], voltas: -8},
- ]
- }
- const tieList = musicList[state.cbsExamSongId as string]
- if (tieList) {
- const partIndex = state.partIndex + ""
- const tie = tieList.find((item) => item.parts.includes(partIndex))
- if (!tie) return
- // 延音线和连线重叠
- if (tie.tieId && tie.tieId.length) {
- for(let tieIndex = 0; tieIndex < tie.tieId.length; tieIndex++){
- const vftie: any = document.querySelector(`#vf-auto${tie.tieId[tieIndex]}-tie`)
- const vfcurve = vftie?.parentNode?.parentNode?.querySelectorAll('.vf-curve')
- if (vfcurve && vfcurve.length){
- for(let i = 0; i < vfcurve.length; i++){
- const result = collisionDetection(vftie, vfcurve[i])
- if (result.isCollision){
- vfcurve[i].style.transform = `translateY(-8px)`;
- break;
- }
- }
- }
- }
- }
-
- // 小节数字
- if (tie.staveSection && tie.staveSection.length) {
- const sectionList = document.querySelectorAll('.vf-StaveSection')
- sectionList.forEach((node, index) => {
- node.classList.add(`section-${index}`)
- })
- for(let i = 0; i < tie.staveSection.length; i++){
- const item: any = document.querySelector( '.' + tie.staveSection[i].id)
- if (item){
- item.style.transform = `translateY(${tie.staveSection[i].y}px)`;
- }
- }
- }
- // modifiers 里面的符号
- if(tie.vfmodifiers && tie.vfmodifiers.length){
- const modifierList = document.querySelectorAll('.vf-modifiers')
- modifierList.forEach((node, index) => {
- node.classList.add(`modifiers-${index}`)
- })
- for(let i = 0; i < tie.vfmodifiers.length; i++){
- const modifier = tie.vfmodifiers[i]
- const item: SVGAElement = document.querySelector( '.' + modifier.id)!
- if (item){
- if (modifier.isLast){
- const lastEle: any = Array.from(item.childNodes).at(-1)
- if (lastEle){
- lastEle.style.transform = `translateY(${modifier.y}px)`;
- }
- }
- }
- }
- }
- // 房子
- if (tie.voltas){
- const modifierList = document.querySelectorAll('.vf-Volta') as unknown as HTMLElement[]
- modifierList.forEach((node, index) => {
- node.style.transform = `translateY(${tie.voltas}px)`;
- })
- }
- // 单个音符
- if (tie.stavenote && tie.stavenote.length) {
- for(let i = 0; i < tie.stavenote.length; i++){
- const item = tie.stavenote[i]
- const ele = document.querySelector('#' + item.id)! as unknown as HTMLElement
- ele && (ele.style.transform = `translateY(${item.y}px)`)
- }
- }
- }
-
- };
- const initNoteCoord = () => {
- const allNoteDot: any = Array.from(document.querySelectorAll('.node-dot'));
- state.noteCoords = allNoteDot.map((note: any) => {
- const note_bbox = note?.getBoundingClientRect?.() || { x: 0, y: 0 };
- return {
- x: note_bbox.x,
- y: note_bbox.y
- }
- })
- console.log(11111,state.noteCoords)
- }
- export const moveGracePosition = (needTrans?: boolean) => {
- /**
- * TODO:曲目:摇篮曲(节奏练习)-倚音位置 特殊处理
- */
- const specialIds = ['1788850864767643649','1788502467554750466','1789839575249596417','1788501975122489346','1796006876341813249'];
- if (specialIds.includes(state.cbsExamSongId) || needTrans) {
- const lastCurve: any = Array.from(document.getElementsByClassName('vf-curve'))?.last();
- if (lastCurve) {
- lastCurve.style.display = 'none';
- }
- if (state.musicRenderType === 'staff') {
- // const transNoteDom = document.getElementById('vf-auto2182')?.getElementsByClassName('vf-modifiers')?.[0];
- // const transBeamDom = document.getElementById('auto3167')?.parentNode?.getElementsByClassName('vf-beams')?.[0];
- // if (transNoteDom) {
- // transNoteDom.style.transform = 'translateX(-0.5rem)';
- // }
- // if (transBeamDom) {
- // transBeamDom.style.transform = 'translateX(-0.5rem)';
- // }
- } else {
- // vf-auto2172 , vf-auto2384
- const signatureDom = document.getElementById('auto2670');
- const signatureDom2 = document.getElementById('auto2710');
- const signatureDom3 = document.getElementById('auto3099');
- const signatureDom4 = document.getElementById('auto3339');
- const needTransLateDom: any = state.cbsExamSongId == '1789839575249596417' && document.getElementById('vf-auto1554')?.getElementsByClassName('vf-modifier')?.[0];
- const arrowDom = state.cbsExamSongId == '1789839575249596417' && document.getElementById('vf-auto1554-lines');
- const needTransLateDom2: any = state.cbsExamSongId == '1788501975122489346' && document.getElementById('vf-auto2116')?.getElementsByClassName('vf-modifier')?.[0];
- const arrowDom2 = state.cbsExamSongId == '1788501975122489346' && document.getElementById('vf-auto2116-lines');
-
- const needTransLateDom3: any = state.cbsExamSongId == '1788502467554750466' && document.getElementById('vf-auto2122')?.getElementsByClassName('vf-modifier')?.[0];
- const arrowDom3 = state.cbsExamSongId == '1788502467554750466' && document.getElementById('vf-auto2122-lines');
- if (signatureDom) signatureDom.style.display = 'none';
- if (signatureDom2) signatureDom2.style.display = 'none';
- if (signatureDom3) signatureDom3.style.display = 'none';
- if (signatureDom4) signatureDom4.style.display = 'none';
- if (needTransLateDom) needTransLateDom.style.transform = 'translateX(-0.65rem)';
- if (needTransLateDom2) needTransLateDom2.style.transform = 'translateX(-0.65rem)';
- if (needTransLateDom3) needTransLateDom3.style.transform = 'translateX(-0.65rem)';
- if (arrowDom) arrowDom.style.transform = 'translateX(-0.65rem)';
- if (arrowDom2) arrowDom2.style.transform = 'translateX(-0.65rem)';
- if (arrowDom3) arrowDom3.style.transform = 'translateX(-0.65rem)';
- if (arrowDom || arrowDom2 || arrowDom3) {
- const path: any = arrowDom ? arrowDom.querySelector('path') : arrowDom2 ? arrowDom2.querySelector('path') : arrowDom3 ? arrowDom3.querySelector('path') : null;
- let d = path?.getAttribute("d");
- if (d) {
- const patchStr = d.split('L')?.last()?.split(" ")?.[0];
- let startX = d.split("M")?.[1]?.split(" ")[0] || 0;
- startX = startX ? Number(startX) : 0;
- let endX = d.split("L")?.last().split(" ")[0] || 0;
- endX = endX ? Number(endX) : 0;
- const distanceX = endX - startX;
- const transX = startX - distanceX;
- d = d.replace(`L${patchStr}`,`L${transX}`);
- path.setAttribute("d", d);
- }
- }
- }
- }
- }
- // 处理一行谱高度太高的问题
- export const limitSingleSvgPageHeight = () => {
- if (state.isSingleLine && !state.isCombineRender) {
- // 获取生成的 SVG 元素
- const osmdSvgPage = document.getElementById('osmdSvgPage1');
- if (osmdSvgPage) {
- // 获取当前的 viewBox 值
- const viewBox = osmdSvgPage.getAttribute('viewBox');
- if (viewBox) {
- // 分割 viewBox 的值,viewBox 形式为 "min-x min-y width height"
- const viewBoxValues = viewBox.split(' ');
- // 修改 viewBox 高度
- const newHeight = 300;
- const staffHeight = osmdSvgPage.querySelector('.staffline')?.getBoundingClientRect()?.height;
- if (viewBoxValues[3] > 300 && staffHeight && staffHeight < 240) {
- const originY = state.isSimplePage ? 0 : 0.25;
- let transY = (240 - staffHeight * state.zoom) / staffHeight;
- transY = state.isSimplePage ? transY / 2 : transY;
- const realY = (originY + transY) * 100 + '%';
- viewBoxValues[3] = newHeight; // 这是第四个值,代表高度
- // 设置新的 viewBox 值
- osmdSvgPage.setAttribute('viewBox', viewBoxValues.join(' '));
- osmdSvgPage.setAttribute('height','240');
- // @ts-ignore
- osmdSvgPage.querySelector('.staffline').style.transform = `translateY(-${realY})`
- }
- }
- }
- }
- }
- const isElementInViewport = (el: any) => {
- const rect = el.getBoundingClientRect();
- return (
- rect.top >= 0 &&
- rect.left >= 0 &&
- rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
- rect.right <= (window.innerWidth || document.documentElement.clientWidth)
- );
- }
- const isNumeric = (str: any) => {
- return /^\d+$/.test(str);
- }
- // 谱面优化
- export const resetFormate = () => {
- container.value = document.getElementById('scrollContainer')
- // if (state.extStyleConfigJson || !container.value) return;
- if (!container.value) return;
- moveGracePosition();
- // setTimeout(() => {
- // initNoteCoord();
- // }, 0);
- const stafflines: SVGAElement[] = Array.from((container.value as HTMLElement).querySelectorAll(".staffline"));
- const baseStep = 4; // 两个元素相间,的间距
- const musicalDistance = 28; // 音阶与第一条线谱的间距,默认设置为28
- for (let i = 0, len = stafflines.length; i < len; i++) {
- const staffline = stafflines[i];
- const stafflineBox = staffline.getBBox();
- const stafflineCenter = stafflineBox.y + stafflineBox.height / 2;
- const vfmeasures: SVGAElement[] = Array.from(staffline.querySelectorAll(".vf-measure"));
- const vfcurve: SVGAElement[] = Array.from(staffline.querySelectorAll(".vf-curve"));
- const vfvoices: SVGAElement[] = Array.from(staffline.querySelectorAll(".vf-measure > .vf-voices"));
- const vfbeams: SVGAElement[] = Array.from(staffline.querySelectorAll(".vf-measure > .vf-beams"));
- const vfties: SVGAElement[] = Array.from(staffline.querySelectorAll(".vf-ties"));
- const vflines: SVGAElement[] = Array.from(staffline.querySelectorAll(".vf-line"));
- const texts: SVGAElement[] = Array.from(staffline.querySelectorAll(".vf-measure > .vf-stave text"));
- const rects: SVGAElement[] = Array.from(staffline.querySelectorAll(".vf-measure > .vf-stave rect[fill=none]"));
- const staveSection: SVGAElement[] = Array.from(staffline.querySelectorAll(".vf-measure .vf-staveSection"));
- const paths: SVGAElement[] = Array.from(staffline.querySelectorAll(".vf-measure > .vf-stave path"));
- const dotModifiers: SVGAElement[] = Array.from(staffline.querySelectorAll(".vf-measure .vf-stopDot"));
- const staves: SVGAElement[] = Array.from(staffline.querySelectorAll(".vf-measure > .vf-stave"));
- const numberVfTexts = Array.from((container.value as HTMLElement).querySelectorAll(".vf-text > text"));
- // 获取第一个线谱的y轴坐标
- const firstLinePathY = paths[0]?.getBBox().y || 0
- // D.C循环标记没有显示完全修复
- // 反复标记 和 小节碰撞
- const repetWord = ["To Coda", "D.S. al Coda", "Coda", "D.C."];
- texts
- .filter((n) => repetWord.includes(n.textContent || ""))
- .forEach((t) => {
- // console.log('文本123',t.textContent,'是否在可视区域内',isElementInViewport(t))
- // D.C循环标记不在可视区域内,需要修复移动其位置信息
- // if (t.textContent?.includes('D.C')) {
- // if (!isElementInViewport(t)) {
- // t.style.transform = `translateX(-40px)`;
- // }
- // }
- vfbeams.forEach((curve) => {
- const result = collisionDetection(t, curve);
- const prePath: SVGAElement = t?.previousSibling as unknown as SVGAElement;
- if (result.isCollision) {
- const shift_y = Number(t.getAttribute("y")) - (result.b1 - result.t2) - baseStep + "";
- t.setAttribute("y", shift_y);
- // console.log('音阶间距',shift_y)
- if (prePath && prePath.getAttribute("stroke-width") === "0.3" && prePath.getAttribute("stroke") === "none" && (prePath.getAttribute("d")?.length || 0) > 3000) {
- prePath.style.transform = `translateY(${-(result.b1 - result.t2 + baseStep)}px)`;
- }
- }
- });
- vfvoices.forEach((curve) => {
- const result = collisionDetection(t, curve);
- const prePath: SVGAElement = t?.previousSibling as unknown as SVGAElement;
- if (result.isCollision) {
- const shift_y = Number(t.getAttribute("y")) - (result.b1 - result.t2) - baseStep + "";
- t.setAttribute("y", shift_y);
- // console.log('音阶间距',shift_y)
- if (prePath && prePath.getAttribute("stroke-width") === "0.3" && prePath.getAttribute("stroke") === "none" && (prePath.getAttribute("d")?.length || 0) > 3000) {
- prePath.style.transform = `translateY(${-(result.b1 - result.t2 + baseStep)}px)`;
- }
- }
- });
- });
- // 文字方框和飞线碰撞
- staveSection.forEach((t) => {
- let shift_y = 0;
- [...vfcurve, ...vfties, ...vfvoices].forEach((curve) => {
- const result = collisionDetection(t, curve);
- if (result.isCollision) {
- shift_y = Math.min(shift_y, result.t2 - result.b1 - baseStep);
- }
- });
- t.style.transform = `translateY(${shift_y}px)`;
- });
- // 文字和小节碰撞
- let vftexts = Array.from(staffline.querySelectorAll(".vf-text > text")).filter((n: any) => n.getBBox().y < stafflineCenter);
- for (let i = 0; i < vftexts.length; i++) {
- const _text = vftexts[i];
- for (let j = 0; j < vftexts.length; j++) {
- if (_text.textContent === 'second time only') {
- // @ts-ignore
- _text.style.transform = `translateY(15px)`;
- }
- if (_text.parentNode === vftexts[j].parentNode) continue;
- const result = collisionDetection(_text as SVGAElement, vftexts[j] as SVGAElement);
- if (result.isCollision) {
- if (_text.textContent === vftexts[j].textContent) {
- vftexts[j].parentNode?.removeChild(vftexts[j]);
- continue;
- }
- }
- }
- }
- vftexts = Array.from(staffline.querySelectorAll(".vf-text > text")).filter((n: any) => n.getBBox().y < stafflineCenter);
- let maxY = 0;
- let _vftexts: SVGAElement[] = [];
- vftexts.forEach((vftext: any) => {
- const textBox = vftext.getBBox();
- if (textBox.y < stafflineCenter) {
- maxY = Math.max(maxY, textBox.y + textBox.height);
- //console.log('音阶间距',textBox.y, textBox.height)
- _vftexts.push(vftext as SVGAElement);
- }
- });
- if (maxY !== 0 && _vftexts.length > 1) {
- _vftexts.forEach((vftext) => {
- vftext.setAttribute("y", maxY + "");
- //console.log('音阶间距',maxY)
- });
- }
- vftexts.forEach((vftext) => {
- [...vfcurve, ...vfmeasures, ...vflines].forEach((vfmeasure) => {
- let result = collisionDetection(vftext as SVGAElement, vfmeasure);
- if (result.isCollision && result.b1 < result.b2 && result.t1 < result.b2 - (result.b2 - result.t2) / 2) {
- const shift_y = Number(vftext.getAttribute("y")) - (result.b1 - result.t2) - baseStep + "";
- vftext.setAttribute("y", shift_y);
- //console.log('音阶间距',shift_y)
- }
- });
- });
- vftexts.forEach((vftext) => {
- vftexts.forEach((text) => {
- if (vftext.parentNode !== text.parentNode && !["marcato", "legato"].includes(vftext.textContent as string)) {
- if (["marcato", "legato"].includes(text.textContent as string)) {
- const result = collisionDetection(vftext as SVGAElement, text as SVGAElement, 30, 30);
- if (result.isCollision) {
- const textBBox = (vftext as SVGAElement).getBBox();
- text.setAttribute("x", textBBox.x + textBBox.width + 5 + "");
- text.setAttribute("y", textBBox.y + textBBox.height - 5 + "");
- //console.log('音阶间距',textBBox.y + textBBox.height - 5 + "")
- }
- } else {
- const result = collisionDetection(vftext as SVGAElement, text as SVGAElement);
- if (result.isCollision) {
- const _y = Number(vftext.getAttribute("y"));
- const shift_y = result.b2 - result.t2 < 24 ? 24 : result.b2 - result.t2;
- text.setAttribute("y", _y - shift_y - 0.5 + "");
- //console.log('音阶间距',_y - shift_y - 0.5 + "")
- }
- }
- }
- });
- });
- // 修改音阶和线谱的间距
- const clefList = ['C', 'G', 'D', 'A', 'E', 'B', 'F#', 'C#', 'G#', 'F', 'Bb', 'Eb', 'Ab', 'Db', 'Gb', 'Cb', 'Fb', 'D#', 'A#', 'E#']
- const btransList = ['Bb', 'Eb', 'Ab', 'Db', 'Gb', 'Cb', 'Fb']
- const jtrsnsList = ['F#', 'C#', 'G#', 'D#', 'A#', 'E#', 'B#']
- vftexts.forEach((label: any) => {
- const labelText = label.textContent as string
- if (clefList.includes(labelText)){
- const _y = Number(label.getAttribute("y"))
- const endY = firstLinePathY ? firstLinePathY - musicalDistance : _y
- label.setAttribute("y", endY)
- }
- if (btransList.includes(labelText)) {
- label.textContent = labelText.replace('b','♭')
- }
- if (jtrsnsList.includes(labelText)) {
- label.textContent = labelText.replace('#','♯')
- }
- });
- // numberVfTexts.forEach((label: any) => {
- // const labelText = label.textContent as string
- // if (isNumeric(labelText)) {
- // const _y = Number(label.getAttribute("y"))
- // const endY = firstLinePathY ? firstLinePathY - musicalDistance : _y
- // label.setAttribute("y", endY)
- // }
- // })
- const vftextBottom = Array.from(staffline.querySelectorAll(".vf-text > text")).filter((n: any) => n.getBBox().y > stafflineCenter);
- const vflineBottom = Array.from(staffline.querySelectorAll(".vf-line")).filter((n: any) => n.getBBox().y > stafflineCenter);
- // 去重
- for (let i = 0; i < vftextBottom.length; i++) {
- const _text = vftextBottom[i];
- for (let j = 0; j < vftextBottom.length; j++) {
- if (_text.parentNode === vftextBottom[j].parentNode) continue;
- const result = collisionDetection(_text as SVGAElement, vftextBottom[j] as SVGAElement);
- if (result.isCollision) {
- if (_text.textContent === vftextBottom[j].textContent) {
- vftextBottom[j].parentNode?.removeChild(vftextBottom[j]);
- continue;
- }
- }
- }
- }
- // 1,2线谱底部文字重叠问题
- vftextBottom.forEach((vftext) => {
- [...vfmeasures].forEach((n) => {
- let result = collisionDetection(vftext as SVGAElement, n);
- if (result.isCollision) {
- vftext.setAttribute("y", result.b2 + Math.abs(result.t1 - Number(vftext.getAttribute("y"))) + "");
- //console.log('音阶间距', result.b2 + Math.abs(result.t1 - Number(vftext.getAttribute("y"))) + "")
- }
- });
- });
- // 如果渐弱渐强有平行的文字
- vflineBottom.forEach((line) => {
- const texts: any[] = [];
- if (line.nextElementSibling?.classList.contains("vf-line")) {
- vftextBottom.forEach((text) => {
- let result = collisionDetection(line as SVGAElement, text as SVGAElement, 20, 20);
- if (result.isCollision) {
- texts.push({
- text: text as SVGAElement,
- result,
- });
- }
- });
- }
- if (texts.length === 1) {
- const result = texts[0].result;
- const text = texts[0].text;
- if (result.x2 + result.w2 < result.x1) {
- // 左
- if (Math.abs(result.y2 - result.y1) > 10) {
- text.setAttribute("y", result.y1 + result.h2 / 2 + "");
- //console.log('音阶间距', result.y1 + result.h2 / 2 + "")
- }
- } else if (result.x2 > result.x1 + result.w1) {
- // 右
- if (Math.abs(result.y2 - result.y1) > 10) {
- text.setAttribute("y", result.y1 + result.h2 / 2 + "");
- //console.log('音阶间距', result.y1 + result.h2 / 2 + "")
- }
- } else {
- if (Math.abs(result.x2 - result.x1) < Math.abs(result.x2 + result.w2 - result.x1 - result.w1)) {
- // console.log(text, '有交集', '靠左')
- text.setAttribute("x", result.x1 - result.w2 - 5 + "");
- if (Math.abs(result.y2 - result.y1) > 10) {
- text.setAttribute("y", result.y1 + result.h2 / 2 + "");
- //console.log('音阶间距', result.y1 + result.h2 / 2 + "")
- }
- } else {
- // console.log(text, '有交集', '靠右')
- text.setAttribute("x", result.x1 + result.w1 + 5 + "");
- if (Math.abs(result.y2 - result.y1) > 10) {
- text.setAttribute("y", result.y1 + result.h2 / 2 + "");
- //console.log('音阶间距', result.y1 + result.h2 / 2 + "")
- }
- }
- }
- } else if (texts.length === 2) {
- const result1 = texts[0].result;
- const text1 = texts[0].text;
- const result2 = texts[1].result;
- const text2 = texts[1].text;
- text1.setAttribute("x", result1.x1 - result1.w2 - 5 + "");
- if (Math.abs(result1.y2 - result1.y1) > 10) {
- text1.setAttribute("y", result1.y1 + result1.h2 / 2 + "");
- //console.log('音阶间距', result1.y1 + result1.h2 / 2 + "")
- }
- text2.setAttribute("x", result2.x1 + result2.w1 + 5 + "");
- if (Math.abs(result2.y2 - result2.y1) > 10) {
- text2.setAttribute("y", result2.y1 + result2.h2 / 2 + "");
- //console.log('音阶间距', result2.y1 + result2.h2 / 2 + "")
- }
- } else if (texts.length === 3) {
- // console.log(texts)
- }
- });
- vftextBottom.forEach((vftext) => {
- vftextBottom.forEach((text) => {
- if (vftext.parentNode !== text.parentNode && !["marcato", "legato", "cresc.", "Cantabile"].includes(vftext.textContent as string)) {
- if (["marcato", "legato", "cresc.", "Cantabile"].includes(text.textContent as string)) {
- const result = collisionDetection(vftext as SVGAElement, text as SVGAElement, 30, 30);
- if (result.isCollision) {
- const textBBox = (vftext as SVGAElement).getBBox();
- text.setAttribute("x", textBBox.x + textBBox.width + 5 + "");
- text.setAttribute("y", textBBox.y + textBBox.height - 5 + "");
- //console.log('音阶间距', textBBox.y + textBBox.height - 5 + "")
- }
- } else {
- const result = collisionDetection(vftext as SVGAElement, text as SVGAElement);
- if (result.isCollision) {
- text.setAttribute("y", result.y1 + result.h1 + result.h2 + "");
- //console.log('音阶间距', result.y1 + result.h1 + result.h2 + "")
- }
- }
- }
- });
- });
- // 同一行内,多个飞线碰撞
- for (let index = 0; index < vfcurve.length; index++) {
- let nextIndex = index + 1;
- const cur = vfcurve[index];
- let next = vfcurve[nextIndex];
- let checkDone = false;
- while (nextIndex <= vfcurve.length - 1 && !checkDone) {
- let result = collisionDetection(cur, next);
- if (result.isCollision) {
- checkDone = true;
- next.style.transform = `translateY(-12px)`;
- } else {
- nextIndex = nextIndex + 1;
- next = vfcurve[nextIndex];
- }
- }
- };
- // 给小节添加背景色
- if (!state.isCreateImg && !state.isPreView) {
- staves.forEach((stave: any,i: number) => {
- const list = [
- Array.from(stave?.querySelectorAll(".vf-StaveSection") || []),
- Array.from(stave?.getElementsByTagName("text") || []),
- Array.from(stave?.querySelectorAll(".vf-Volta") || []),
- Array.from(stave?.querySelectorAll(".vf-clef") || []),
- Array.from(stave?.querySelectorAll(".vf-keysignature") || []),
- Array.from(stave?.querySelectorAll(".vf-Repetition") || []),
- ].flat();
- try {
- if (list.length) {
- list.forEach((_el: any) => {
- if (_el.parentNode === stave) {
- stave?.removeChild(_el)
- _el?.style?.setProperty("display", "none");
- }
- });
- }
- } catch (error) {}
- const bbox = stave?.getBBox() || {};
- const bgColor = 'transparent';
- const botColor = 'transparent';
- const rect = `<rect class="vf-custom-bg" x="${bbox.x}" y="${bbox.y}" width="${bbox.width}" height="${bbox.height}" fill=${bgColor} />`
- const rectBottom = `<rect class="vf-custom-bot" x="${bbox.x}" y="${bbox.y+bbox.height}" width="${bbox.width}" height="7.5" fill=${botColor} />`
- // const filterDom = `<defs>
- // <filter id="shadow">
- // <feDropShadow dx="5" dy="5" stdDeviation="3" flood-color="black" />
- // </filter>
- // </defs>`
- const customG = `<g>${rect}${rectBottom}</g>`
- try {
- if (list.length) {
- for(const _el of list) {
- if (_el?.parentElement?.classList?.contains('vf-StaveSection')) {
- continue;
- }
- stave?.appendChild(_el)
- _el?.style?.removeProperty("display");
- }
- }
- } catch (error) {}
- stave.innerHTML = customG + stave.innerHTML;
- });
- state.vfmeasures = state.vfmeasures.concat(vfmeasures);
- }
- dotModifiers.forEach((group: any) => {
- let parent = group?.parentElement; // 获取父元素
- // 如果需要找更外层的祖先元素,可以一直迭代
- while (parent && !parent.classList?.contains('vf-measure') && parent.tagName !== 'body' && parent) { // 假设你想找到最外层的 DIV
- parent = parent.parentElement;
- }
- const parentY = parent?.querySelector('.vf-custom-bg')?.getBoundingClientRect()?.y || 0;
- const dotY = group?.getBoundingClientRect()?.y || 0;
- const distanceY = parentY - dotY;
- const translateY = 15 - distanceY;
- // console.log('距离111',translateY)
- group.setAttribute('transform', `translate(3,${-translateY})`)
- // if (state.musicRenderType === 'fixedTone') {
- // // group.setAttribute('transform', 'translate(3,-12)')
- // } else {
- // // group.setAttribute('transform', 'translate(3,-7)')
- // }
- });
- // 修复D.C、D.S等渲染位置不对的问题
- const repairWord = ["D.S.", "D.C.", "Fine"];
- [...vfmeasures].forEach((measure: any) => {
- const needRepairTexts = measure.querySelectorAll('text').length ? Array.from(measure.querySelectorAll('text'))?.filter((item: any) => repairWord.includes(item?.textContent)) : [];
- if (needRepairTexts.length) {
- // 该小节结束位置的x坐标
- const measureCoordinate = measure?.querySelector('.vf-custom-bg')?.getBBox() || null
- const measureEndX = measureCoordinate ? measureCoordinate?.x + measureCoordinate?.width - 30 : 0;
- needRepairTexts.forEach((text: any) => {
- text?.setAttribute('x', measureEndX)
- })
- }
- });
- }
- if (!state.isCombineRender && state.isSingleLine) {
- transSinglePage();
- }
- // 多行谱,拍号可能被遮挡,需要移动谱面的位置
- if (!state.isSingleLine) {
- transMultiPosition();
- }
- // setTimeout(() => this.resetGlobalText());
- };
- // 一行谱时,五线谱/简谱的谱面staffLine,居中显示
- const transSinglePage = () => {
- if (state.isSingleLine && !state.isSimplePage) {
- const svgPage = document?.getElementById('osmdSvgPage1')?.getBoundingClientRect();
- const staffLine = document?.querySelector('.staffline')?.getBoundingClientRect();
- if (svgPage && staffLine && svgPage.height > 200) {
- // 需要上移的距离
- // console.log('need',svgPage.height,staffLine.height)
- const rate = svgPage.height > 400 ? 1.2 : 2;
- let needTransTop = (svgPage.height - staffLine.height) / rate;
- // 给个安全距离
- const maxTop = staffLine.top - svgPage.top - 40
- needTransTop = Math.min(maxTop, needTransTop)
- // @ts-ignore
- document.getElementById('osmdSvgPage1').style.transform = `translateY(-${needTransTop}px)`;
- // 一行谱需要同时偏移光标的位置
- const cursorDom = document.getElementById('cursorImg-0') || null;
- if (cursorDom) {
- cursorDom.style.transform = state.musicRenderType === 'staff' ? `translate(11Px, -${needTransTop}px)` : `translate(6.3Px, -${needTransTop}px)`;
- }
- // document.querySelector('.staffline').style.transform = `translateY(-${needTransTop}px)`;
- // const musicLine = document.querySelector('.staffline').querySelector('.vf-measure').querySelector('.vf-custom-bg').getBoundingClientRect();
- // const needTransDistance = svgPage.height / 2 - (musicLine.top - svgPage.top)
- // console.log('svg移动距离',needTransDistance)
- // // @ts-ignore
- // document.getElementById('osmdSvgPage1').style.transform = `translateY(${needTransDistance}px)`
- }
- }
- if (state.isSimplePage) {
- const svgPage = document?.getElementById('osmdSvgPage1')?.getBoundingClientRect();
- const staffLine = document?.querySelector('.staffline')?.getBoundingClientRect();
- if (svgPage && staffLine) {
- const needY = svgPage.height - (staffLine.y+staffLine.height) - 10;
- // @ts-ignore
- document.getElementById('osmdSvgPage1').style.transform = `translateY(${needY}px)`;
- // 一行谱需要同时偏移光标的位置
- const cursorDom = document.getElementById('cursorImg-0') || null;
- if (cursorDom) {
- cursorDom.style.transform = state.musicRenderType === 'staff' ? `translate(6Px, ${needY}px)` : `translate(6.3Px, ${needY}px)`;
- console.log('一行谱11111')
- }
- }
- }
- }
- const transMultiPosition = () => {
- const svgPage = document?.getElementById('osmdSvgPage1')?.getBoundingClientRect();
- const staffLine = document?.querySelector('.staffline')?.getBoundingClientRect();
- if (svgPage && staffLine && staffLine.y < svgPage.y) {
- const needY = svgPage.y - staffLine.y + 5;
- // @ts-ignore
- document.querySelector('.staffline').style.transform = `translateY(${needY}px)`;
- }
- }
- // 技巧文本
- const resetGlobalText = () => {
- const svg = container.value.querySelector("svg");
- if (!svg) return;
- const svgBBox = svg.getBBox();
- let vfstavetempo: SVGAElement[] = Array.from(container.value.querySelectorAll(".vf-stavetempo")).reduce((eles: SVGAElement[], value: any) => {
- if (eles.find((n) => n.outerHTML === value.outerHTML)) value?.parentNode?.removeChild(value);
- else eles.push(value);
- return eles;
- }, []);
- const staffline: SVGAElement[] = Array.from(container.value.querySelectorAll(".staffline"));
- const vfmeasures: SVGAElement[] = Array.from(container.value.querySelectorAll(".staffline > .vf-measure"));
- const vftexts: SVGAElement[] = Array.from(container.value.querySelectorAll(".staffline > .vf-text"));
- const vfcurves: SVGAElement[] = Array.from(container.value.querySelectorAll(".staffline > .vf-curve"));
- vfstavetempo.forEach((child: SVGAElement) => {
- let _y = 0;
- [...vfmeasures, ...vftexts, ...vfcurves].forEach((ele) => {
- const result = collisionDetection(child as SVGAElement, ele);
- if (result.isCollision && (result.b1 < result.b2 || result.r1 > result.l2 || result.l1 < result.r2)) {
- _y = Math.min(_y, result.t2 - result.b1);
- }
- });
- if (_y !== 0) {
- child.style.transform = `translateY(${_y}px)`;
- }
- const childBBox = child.getBBox();
- const rightY = (childBBox.x + childBBox.width) * 0.7 - Number(svg.getAttribute("width"));
- if (rightY > 0) {
- [...staffline, ...vfstavetempo].forEach((tempo) => {
- if (child != tempo) {
- const result = collisionDetection(child as SVGAElement, tempo, Math.abs(rightY), Math.abs(_y));
- if (result.isCollision) {
- _y = result.t2 - result.b1;
- }
- }
- });
- child.style.transform = `translate(-${rightY / 0.7}px,${_y}px)`;
- }
- });
- if (svgBBox.y < 0) {
- svg.setAttribute("height", Number(svg.getAttribute("height")) - svgBBox.y + 10);
- }
- };
- // 碰撞检测
- const collisionDetection = (a: SVGAElement, b: SVGAElement, distance: number = 0, distance_y: number = 0) => {
- const abbox = a.getBBox();
- const bbbox = b.getBBox();
- let t1 = abbox.y - distance_y;
- let l1 = abbox.x - distance;
- let r1 = abbox.x + abbox.width + distance;
- let b1 = abbox.y + abbox.height + distance_y;
- let t2 = bbbox.y;
- let l2 = bbbox.x;
- let r2 = bbbox.x + bbbox.width;
- let b2 = bbbox.y + bbbox.height;
- if (b1 < t2 || l1 > r2 || t1 > b2 || r1 < l2) {
- // 表示没碰上
- return {
- isCollision: false,
- t1,
- l1,
- r1,
- b1,
- t2,
- l2,
- r2,
- b2,
- x1: abbox.x,
- y1: abbox.y,
- x2: bbbox.x,
- y2: bbbox.y,
- h1: abbox.height,
- h2: bbbox.height,
- w1: abbox.width,
- w2: bbbox.width,
- };
- } else {
- return {
- isCollision: true,
- t1,
- l1,
- r1,
- b1,
- t2,
- l2,
- r2,
- b2,
- x1: abbox.x,
- y1: abbox.y,
- x2: bbbox.x,
- y2: bbbox.y,
- h1: abbox.height,
- h2: bbbox.height,
- w1: abbox.width,
- w2: bbbox.width,
- };
- }
- };
- /** 全局曲谱配置 */
- export const setGlobalMusicSheet = () => {
- const partIndex = state.partIndex + ""
- /** 延音线方向问题 start */
- const stavetieList = [
- {id: '12644', part_index: '25', direction: 1}
- ]
- const tieItem = stavetieList.find(({id, part_index}) => {
- return id == state.cbsExamSongId && part_index == partIndex
- })
- setGlobalData('tieDirection', tieItem ? tieItem.direction : undefined)
- /** 延音线方向问题 end */
-
- const graceList = [
- {id: '3509', part_index: '16', direction: 1}
- ]
- const graceItem = graceList.find(({id, part_index}) => {
- return id == state.cbsExamSongId && part_index == partIndex
- })
- if (graceItem){
- setGlobalData('graceCustom', {direction: graceItem.direction})
- }
- const bassDrumList = [
- {id: '3030', part_index: '17', line: 4},
- {id: '12704', part_index: '23', line: 3}
- ]
- const bassDrumItem = bassDrumList.find(({id, part_index}) => {
- return id == state.cbsExamSongId && part_index == partIndex
- })
- if (bassDrumItem){
- setGlobalData('customBassDrum', bassDrumItem.line)
- }
- /** 打击乐多声部,双声部休止符重叠 end */
-
- /** 符杆朝向 */
- const stemDirectionList = [
- {
- id: '11654',
- part_index: '16',
- stemNotes: [
- {id: 124, direction: 0},
- {id: 125, direction: 0},
- {id: 126, direction: 0},
- {id: 127, direction: 0},
- {id: 128, direction: 0}
- ]
- },
- {
- id: '3581',
- part_index: '4',
- stemNotes: [
- {id: 380, direction: 1},
- ]
- },
- {
- id: '3470',
- part_index: '0',
- stemNotes: [
- {id: 36, direction: 1},
- {id: 37, direction: 1},
- ]
- },
- {
- id: '3470',
- part_index: '11',
- stemNotes: [
- {id: 33, direction: 1},
- {id: 56, direction: 1},
- ]
- },
- {
- id: '12644',
- part_index: '22',
- stemNotes: [
- {id: 22, direction: 1},
- {id: 26, direction: 1},
- {id: 135, direction: 1},
- {id: 163, direction: 1},
- {id: 199, direction: 1},
- {id: 204, direction: 1},
- {id: 206, direction: 1},
- {id: 208, direction: 1},
- {id: 210, direction: 1},
- {id: 213, direction: 1},
- ]
- },
- {
- id: '12303',
- part_index: '18',
- stemNotes: [
- {id: 1, direction: 1},
- {id: 4, direction: 1},
- {id: 6, direction: 1},
- {id: 9, direction: 1},
- {id: 12, direction: 1},
- {id: 14, direction: 1},
- ]
- },
- {
- id: '12669',
- part_index: '24',
- stemNotes: [
- {id: 65, direction: 1},
- {id: 296, direction: 1},
- {id: 298, direction: 1},
- {id: 300, direction: 1},
- {id: 338, direction: 1},
- ]
- },
- {
- id: '12420',
- part_index: '21',
- stemNotes: [
- {id: 614, direction: 0},
- {id: 617, direction: 0},
- {id: 619, direction: 0},
- {id: 621, direction: 0},
- ]
- },
- {
- id: '12711',
- part_index: '22',
- stemNotes: []
- },
- {
- id: '12973',
- part_index: '21',
- stemNotes: [
- {id: 619, direction: 1},
- {id: 622, direction: 1},
- {id: 745, direction: 1},
- ]
- },
- ]
- const stemDirectionItem = stemDirectionList.find(({id, part_index}) => {
- return id == state.cbsExamSongId && part_index == partIndex
- })
- if (stemDirectionItem) {
- setGlobalData('stemDirectionNote', stemDirectionItem.stemNotes)
- }
-
- /** vfcure */
- const vfcurveList = [
- {
- id: '12711',
- part_index: '4',
- vfcurve: [
- {MeasureNumberXML: 25, index: 1, bezierEndControlPt: {y: -2}},
- {MeasureNumberXML: 33, index: 1, bezierEndControlPt: {y: -2}},
- ]
- },
- {
- id: '12059',
- part_index: '0',
- vfcurve: [
- {MeasureNumberXML: 15, bezierEndControlPt: {y: 2.8}, bezierEndPt:{y: 1.1}},
- {MeasureNumberXML: 16, bezierEndControlPt: {y: -1}},
- {MeasureNumberXML: 19, index: 1, bezierEndControlPt: {y: 2}},
- {MeasureNumberXML: 20, bezierEndControlPt: {y: -1}},
- {MeasureNumberXML: 42, index: 1, bezierEndControlPt: {y: -1.5}, bezierStartControlPt: {y: -1.5}},
- {MeasureNumberXML: 46, index: 3, bezierEndControlPt: {y: -1.5}, bezierStartControlPt: {y: -1.5}},
- ]
- },
- {
- id: '12668',
- part_index: '11',
- vfcurve: [
- {MeasureNumberXML: 8, index: 2, bezierEndControlPt: {y: -3}, bezierStartControlPt:{y: -3}, bezierEndPt:{y: -1}},
- ]
- },
- {
- id: '11976',
- part_index: '0',
- vfcurve: [
- {MeasureNumberXML: 14, index: 4, bezierEndControlPt: {y: -3}},
- {MeasureNumberXML: 14, index: 1, bezierEndPt: {y: 1.5}, bezierEndControlPt: {y: 1}},
- ]
- },
- ]
- const vfcurveItem = vfcurveList.find(({id, part_index}) => {
- return id == state.cbsExamSongId && part_index == partIndex
- })
- if (vfcurveItem) {
- setGlobalData('vfcurveItem', vfcurveItem.vfcurve)
- }
- /** drum set声部 重音 */
- const customArtPositionList = [
- {id: '12644', part_index: '25'}
- ]
- const customArtPositionItem = customArtPositionList.find(({id, part_index}) => {
- return id == state.cbsExamSongId && part_index == partIndex
- })
- if (customArtPositionItem) {
- setGlobalData('customArtPosition', true)
- }
- /** 全声部声部 - & 全音符 */
- const customTenutoList = [
- {id: '12645', part_index: '5'}
- ]
- const customTenutoItem = customTenutoList.find(({id, part_index}) => {
- return id == state.cbsExamSongId && part_index == partIndex
- })
- if (customTenutoItem) {
- setGlobalData('customTenutoItem', true)
- }
- /** 全声部声部 > */
- const customAccentList = [
- {id: '12711', part_index: '22'},
- {id: '12711', part_index: '25'},
- ]
- const customAccentItem = customAccentList.find(({id, part_index}) => {
- return id == state.cbsExamSongId && part_index == partIndex
- })
- if (customAccentItem || state.isEvxml) {
- setGlobalData('customAccentItem', true)
- }
- /** 全声部声部 + */
- const customLefthandpizzicatoList = [
- {id: '12711', part_index: '25'},
- {id: '7755', part_index: '10'},
- {id: '6226', part_index: '16'},
- ]
- const customLefthandpizzicatoItem = customLefthandpizzicatoList.find(({id, part_index}) => {
- return id == state.cbsExamSongId && part_index == partIndex
- })
- if (customLefthandpizzicatoItem) {
- setGlobalData('customLefthandpizzicatoItem', true)
- }
- }
- /** 设置自定义音符数据 */
- export const setCustomNoteRealValue = () => {
- const detailId = state.cbsExamSongId + "";
- if (["12667", "12673"].includes(detailId)){
- customData.customNoteCurrentTime = true
- }
- };
- /** 转换简谱的全休止符和二分休止符 */
- export const transferJianNote = (measure: any, divisions: number, preBeats: number, preBeatType: number) => {
- const multipleXs = preBeatType / 4;
- const notes = measure.getElementsByTagName("note")
- for (const note of notes) {
- // 是否需要考虑带上附点
- let needAddDot = true;
- const noteType = note.getElementsByTagName("type")?.[0]?.textContent || '';
- if ((noteType === 'whole' || noteType === 'half') && note.getElementsByTagName("rest").length) {
- // 4/4拍,3/4拍
- if (preBeatType === 4) {
- let maxNumber = noteType === 'half' ? 2 : preBeats / multipleXs;
- if (noteType === 'whole') {
- // 有可能是全休止符,但是该小节又不是整小节都休止,此时这个全休止符不能按照整小节休止来计算
- const noteDivisions = parseInt(note.getElementsByTagName("duration")[0]?.textContent);
- if (noteDivisions/divisions !== preBeats) {
- maxNumber = 4;
- } else {
- // 满足了时值,则不需要考虑加上附点
- needAddDot = false;
- }
- }
- // 如果音符带附点,需要判断处理下
- if (note.getElementsByTagName("dot").length && needAddDot) {
- maxNumber = noteType === 'whole' ? maxNumber + 2 : maxNumber + 1;
- }
- if (!Number.isInteger(maxNumber)) {
- return;
- }
- // console.log('几个1/4音符',maxNumber)
- let quarterNoteNumber = 1;
- while (quarterNoteNumber <= maxNumber) {
- const newnote = document.createElement('note');
- newnote.innerHTML = `
- <rest></rest>
- <duration>${divisions}</duration>
- <voice>1</voice>
- <type>quarter</type>`
- measure.insertBefore(newnote, note);
- quarterNoteNumber += 1;
- };
- measure.removeChild(note);
- } else if (preBeats === 3 && preBeatType === 8) {
- const maxNumber = noteType === 'half' ? 2 : 3;
- let quarterNoteNumber = 1;
- while (quarterNoteNumber <= maxNumber) {
- const newnote = document.createElement('note');
- newnote.innerHTML = `
- <rest></rest>
- <duration>${divisions/2}</duration>
- <voice>1</voice>
- <type>eighth</type>`
- measure.insertBefore(newnote, note);
- quarterNoteNumber += 1;
- };
- measure.removeChild(note);
- } else if (preBeats === 5 && preBeatType === 8) {
- if (noteType === 'whole') {
- const newnote = document.createElement('note');
- newnote.innerHTML = `
- <rest></rest>
- <duration>${divisions+divisions/2}</duration>
- <voice>1</voice>
- <type>quarter</type>
- <dot></dot>`
- measure.insertBefore(newnote, note);
- const newnote2 = document.createElement('note');
- newnote2.innerHTML = `
- <rest></rest>
- <duration>${divisions}</duration>
- <voice>1</voice>
- <type>quarter</type>`
- measure.insertBefore(newnote2, note);
- measure.removeChild(note);
- } else if (noteType === 'half') {
- dealDotHalfNote(measure, divisions, note)
- }
- } else if (preBeats === 6 && preBeatType === 8) {
- if (noteType === 'whole') {
- const maxNumber = 2;
- let quarterNoteNumber = 1;
- while (quarterNoteNumber <= maxNumber) {
- const newnote = document.createElement('note');
- newnote.innerHTML = `
- <rest></rest>
- <duration>${divisions+divisions/2}</duration>
- <voice>1</voice>
- <type>quarter</type>
- <dot></dot>`
- measure.insertBefore(newnote, note);
- quarterNoteNumber += 1;
- };
- measure.removeChild(note);
- } else if (noteType === 'half') {
- dealDotHalfNote(measure, divisions, note)
- }
- } else if (preBeats === 7 && preBeatType === 8) {
- if (noteType === 'whole') {
- const newnote2 = document.createElement('note');
- newnote2.innerHTML = `
- <rest></rest>
- <duration>${divisions+divisions/2}</duration>
- <voice>1</voice>
- <type>quarter</type>
- <dot></dot>`
- measure.insertBefore(newnote2, note);
- const maxNumber = 2;
- let quarterNoteNumber = 1;
- while (quarterNoteNumber <= maxNumber) {
- const newnote = document.createElement('note');
- newnote.innerHTML = `
- <rest></rest>
- <duration>${divisions}</duration>
- <voice>1</voice>
- <type>quarter</type>`
- measure.insertBefore(newnote, note);
- quarterNoteNumber += 1;
- };
- measure.removeChild(note);
- } else if (noteType === 'half') {
- dealDotHalfNote(measure, divisions, note)
- }
- } else if (preBeats === 9 && preBeatType === 8) {
- if (noteType === 'whole') {
- const maxNumber = 3;
- let quarterNoteNumber = 1;
- while (quarterNoteNumber <= maxNumber) {
- const newnote = document.createElement('note');
- newnote.innerHTML = `
- <rest></rest>
- <duration>${divisions+divisions/2}</duration>
- <voice>1</voice>
- <type>quarter</type>
- <dot></dot>`
- measure.insertBefore(newnote, note);
- quarterNoteNumber += 1;
- };
- measure.removeChild(note);
- } else if (noteType === 'half') {
- dealDotHalfNote(measure, divisions, note)
- }
- } else if (preBeats === 12 && preBeatType === 8) {
- if (noteType === 'whole') {
- const maxNumber = 4;
- let quarterNoteNumber = 1;
- while (quarterNoteNumber <= maxNumber) {
- const newnote = document.createElement('note');
- newnote.innerHTML = `
- <rest></rest>
- <duration>${divisions+divisions/2}</duration>
- <voice>1</voice>
- <type>quarter</type>
- <dot></dot>`
- measure.insertBefore(newnote, note);
- quarterNoteNumber += 1;
- };
- measure.removeChild(note);
- } else if (noteType === 'half') {
- dealDotHalfNote(measure, divisions, note)
- }
- }
- }
- }
- }
- /** 八几排的小节,二分休止符带附点 */
- const dealDotHalfNote = (measure: any, divisions: number, note: any) => {
- // 如果音符带附点,需要判断处理下
- if (note.getElementsByTagName("dot").length) {
- const maxNumber = 2;
- let quarterNoteNumber = 1;
- while (quarterNoteNumber <= maxNumber) {
- const newnote = document.createElement('note');
- newnote.innerHTML = `
- <rest></rest>
- <duration>${divisions+divisions/2}</duration>
- <voice>1</voice>
- <type>quarter</type>
- <dot></dot>`
- measure.insertBefore(newnote, note);
- quarterNoteNumber += 1;
- };
- measure.removeChild(note);
- } else {
- const newnote = document.createElement('note');
- newnote.innerHTML = `
- <rest></rest>
- <duration>${divisions+divisions/2}</duration>
- <voice>1</voice>
- <type>quarter</type>
- <dot></dot>`
- measure.insertBefore(newnote, note);
- const newnote2 = document.createElement('note');
- newnote2.innerHTML = `
- <rest></rest>
- <duration>${divisions/2}</duration>
- <voice>1</voice>
- <type>eighth</type>`
- measure.insertBefore(newnote2, note);
- measure.removeChild(note);
- }
- }
|