|
@@ -541,22 +541,189 @@ export const onlyVisible = (xml: string, partIndex: number, resourceType?: strin
|
|
|
return new XMLSerializer().serializeToString(appoggianceFormate(xmlParse));
|
|
|
};
|
|
|
|
|
|
-export const onlyVisible2 = (xml: string): string => {
|
|
|
+export const onlyVisible2 = (xml: string, partIndexs: Array<any>, resourceType?: string): string => {
|
|
|
if (!xml) return "";
|
|
|
// console.log('原始xml')
|
|
|
- //const detailId = state.examSongId + "";
|
|
|
- console.time('解析xml 耗时5')
|
|
|
- const xmlParse = new DOMParser().parseFromString(xml, "text/xml");
|
|
|
- console.timeEnd('解析xml 耗时5')
|
|
|
+ const detailId = state.examSongId + "";
|
|
|
+ //console.time('解析xml 耗时4')
|
|
|
+ // const xmlParse = new DOMParser().parseFromString(xml, "text/xml");
|
|
|
+ const xmlParse = xmlDocRef.value ? xmlDocRef.value : new DOMParser().parseFromString(xml, "text/xml");
|
|
|
+ //console.timeEnd('解析xml 耗时4')
|
|
|
const partList = xmlParse.getElementsByTagName("part-list")?.[0]?.getElementsByTagName("score-part") || [];
|
|
|
- //const partListNames = Array.from(partList).map((item) => item.getElementsByTagName("part-name")?.[0]?.textContent?.trim() || "");
|
|
|
- //state.partListNames = partListNames;
|
|
|
- Array.from(partList).forEach((part) => {
|
|
|
- let partListName = part.getElementsByTagName("part-name")?.[0]?.textContent?.trim();
|
|
|
- if (!state.canSelectTracks.includes(partListName)) {
|
|
|
- part.parentNode?.removeChild(part);
|
|
|
+ const partListNames = Array.from(partList).map((item) => item.getElementsByTagName("part-name")?.[0]?.textContent?.trim() || "");
|
|
|
+ const parts: any = xmlParse.getElementsByTagName("part");
|
|
|
+ // const firstTimeInfo = parts[0]?.getElementsByTagName('metronome')[0]?.parentElement?.parentElement?.cloneNode(true)
|
|
|
+ const hasMeasureIdx = Array.from(parts).findIndex((item: any) => item.getElementsByTagName("measure").length) || 0;
|
|
|
+ const firstMeasures = [...parts[hasMeasureIdx]?.getElementsByTagName("measure")];
|
|
|
+ state.totalMeasureNumber = firstMeasures.length || [...parts[1]?.getElementsByTagName("measure")]?.length
|
|
|
+ const metronomes = [...parts[0]?.getElementsByTagName("metronome")];
|
|
|
+ const words = [...parts[0]?.getElementsByTagName("words")];
|
|
|
+ const codas = [...parts[0]?.getElementsByTagName("coda")];
|
|
|
+ const rehearsals = [...parts[0]?.getElementsByTagName("rehearsal")];
|
|
|
+
|
|
|
+ /** 第一分谱如果是约定的配置分谱则跳过 */
|
|
|
+ if (partListNames[0]?.toLocaleUpperCase?.() === "COMMON") {
|
|
|
+ partIndexs = partIndexs.map(item => item + 1)
|
|
|
+ //partListNames.shift();
|
|
|
+ }
|
|
|
+ const visiblePartInfo = partList[partIndexs[0]];
|
|
|
+ let ids: any = [];
|
|
|
+ partIndexs.forEach(item => {
|
|
|
+ if (partList[item]) {
|
|
|
+ ids.push(partList[item]?.getAttribute("id"))
|
|
|
}
|
|
|
- });
|
|
|
+ })
|
|
|
+ // console.log(visiblePartInfo, partIndex)
|
|
|
+ // 根据后台已选择的分轨筛选出能切换的声轨
|
|
|
+ //state.partListNames = partListNames;
|
|
|
+ // console.log('分轨名称',state.partListNames)
|
|
|
+ if (visiblePartInfo && ids.length) {
|
|
|
+ const id = visiblePartInfo.getAttribute("id");
|
|
|
+ Array.from(parts).forEach((part: any) => {
|
|
|
+ if (part && !ids.includes(part.getAttribute("id")) ) {
|
|
|
+ part.parentNode?.removeChild(part);
|
|
|
+ // 不等于第一行才添加避免重复添加
|
|
|
+ } else if (part && part.getAttribute("id") !== "P1") {
|
|
|
+ if (part && part.getAttribute("id") === id) {
|
|
|
+ // 速度标记仅保留最后一个
|
|
|
+ const metronomeData: {
|
|
|
+ [key in string]: Element;
|
|
|
+ } = {};
|
|
|
+ for (let i = 0; i < metronomes.length; i++) {
|
|
|
+ const metronome = metronomes[i];
|
|
|
+ const metronomeContainer = metronome.parentElement?.parentElement?.parentElement;
|
|
|
+ if (metronomeContainer) {
|
|
|
+ const index = firstMeasures.indexOf(metronomeContainer);
|
|
|
+ metronomeData[index] = metronome;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Object.values(metronomeData).forEach((metronome) => {
|
|
|
+ const metronomeContainer: any = metronome.parentElement?.parentElement;
|
|
|
+ const parentMeasure: any = metronomeContainer?.parentElement;
|
|
|
+ const measureMetronomes = [...(parentMeasure?.childNodes || [])];
|
|
|
+ const metronomesIndex = metronomeContainer ? measureMetronomes.indexOf(metronomeContainer) : -1;
|
|
|
+ // console.log(parentMeasure)
|
|
|
+ if (parentMeasure && metronomesIndex > -1) {
|
|
|
+ const index = firstMeasures.indexOf(parentMeasure);
|
|
|
+ const activeMeasure = part.getElementsByTagName("measure")[index];
|
|
|
+ setElementNoteBefore(metronomeContainer, parentMeasure, activeMeasure);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ /** word比较特殊需要精确到note位置 */
|
|
|
+ words.forEach((word) => {
|
|
|
+ let text = word.textContent || "";
|
|
|
+ text = ["cresc."].includes(text) ? "" : text;
|
|
|
+ if ((isSpecialMark(text) || isSpeedKeyword(text) || isGradientWords(text) || isRepeatWord(text) || GRADIENT_SPEED_RESET_TAG) && text) {
|
|
|
+ const wordContainer = word.parentElement?.parentElement;
|
|
|
+ const parentMeasure = wordContainer?.parentElement;
|
|
|
+ const measureWords = [...(parentMeasure?.childNodes || [])];
|
|
|
+ const wordIndex = wordContainer ? measureWords.indexOf(wordContainer) : -1;
|
|
|
+ if (wordContainer && parentMeasure && wordIndex > -1) {
|
|
|
+ const index = firstMeasures.indexOf(parentMeasure);
|
|
|
+ const activeMeasure = part.getElementsByTagName("measure")[index];
|
|
|
+ // 找当前小节是否包含word标签
|
|
|
+ const _words = Array.from(activeMeasure?.getElementsByTagName("words") || []);
|
|
|
+ // 遍历word标签,检查是否和第一小节重复,如果有重复则不平移word
|
|
|
+ const total = _words.reduce((total: any, _word: any) => {
|
|
|
+ if (_word.textContent?.includes(text)) {
|
|
|
+ total++;
|
|
|
+ }
|
|
|
+ return total;
|
|
|
+ }, 0);
|
|
|
+ if (total === 0) {
|
|
|
+ if (["12280"].includes(detailId)) {
|
|
|
+ activeMeasure?.insertBefore(wordContainer.cloneNode(true), activeMeasure?.childNodes[wordIndex]);
|
|
|
+ } else {
|
|
|
+ setElementNoteBefore(wordContainer, parentMeasure, activeMeasure);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ /** word比较特殊需要精确到note位置 */
|
|
|
+ codas.forEach((coda) => {
|
|
|
+ const wordContainer = coda.parentElement?.parentElement;
|
|
|
+ const parentMeasure = wordContainer?.parentElement;
|
|
|
+ const measureWords = [...(parentMeasure?.childNodes || [])];
|
|
|
+ const wordIndex = wordContainer ? measureWords.indexOf(wordContainer) : -1;
|
|
|
+ if (wordContainer && parentMeasure && wordIndex > -1) {
|
|
|
+ const index = firstMeasures.indexOf(parentMeasure);
|
|
|
+ const activeMeasure = part.getElementsByTagName("measure")[index];
|
|
|
+ if (["12280"].includes(detailId)) {
|
|
|
+ activeMeasure?.insertBefore(wordContainer.cloneNode(true), activeMeasure?.childNodes[wordIndex]);
|
|
|
+ } else {
|
|
|
+ setElementNoteBefore(wordContainer, parentMeasure, activeMeasure);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ rehearsals.forEach((rehearsal) => {
|
|
|
+ const container = rehearsal.parentElement?.parentElement;
|
|
|
+ const parentMeasure = container?.parentElement;
|
|
|
+ // console.log(rehearsal)
|
|
|
+ if (parentMeasure) {
|
|
|
+ const index = firstMeasures.indexOf(parentMeasure);
|
|
|
+ part.getElementsByTagName("measure")[index]?.appendChild(container.cloneNode(true));
|
|
|
+ // console.log(index, parentMeasure, firstMeasures.indexOf(parentMeasure))
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ } else {
|
|
|
+ if (part && part.getAttribute("id") === id) {
|
|
|
+ words.forEach((word, idx) => {
|
|
|
+ const text = word.textContent || "";
|
|
|
+ // if (idx == 0 && text) {
|
|
|
+ // word.textContent = '测试一下'
|
|
|
+ // word.setAttribute('default-y',60)
|
|
|
+ // word.setAttribute('margin-left',300)
|
|
|
+ // word.setAttribute('y',300)
|
|
|
+ // word.outerHTML = '<words default-x="155" default-y="100" justify="right" valign="middle" font-family="SimHei" font-style="normal" font-size="11.9365" font-weight="normal">哈哈哈哈哈</words>'
|
|
|
+ // }
|
|
|
+ if (isSpeedKeyword(text) && text) {
|
|
|
+ const wordContainer = word.parentElement?.parentElement?.parentElement;
|
|
|
+ if (wordContainer && wordContainer.firstElementChild && wordContainer.firstElementChild !== word) {
|
|
|
+ const wordParent = word.parentElement?.parentElement;
|
|
|
+ const fisrt = wordContainer.firstElementChild;
|
|
|
+ wordContainer.insertBefore(wordParent, fisrt);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // 最后一个小节的结束线元素不在最后 调整
|
|
|
+ if (part && part.getAttribute("id") === id) {
|
|
|
+ if (!resourceType) {
|
|
|
+ const backups = Array.from(part.getElementsByTagName('backup')) || []
|
|
|
+ for (let backup of backups) {
|
|
|
+ // @ts-ignore
|
|
|
+ if (backup && backup?.getElementsByTagName('duration')?.length) {
|
|
|
+ state.isSingleMutliTrack = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ const barlines = part.getElementsByTagName("barline");
|
|
|
+ const lastParent = barlines[barlines.length - 1]?.parentElement;
|
|
|
+ if (lastParent?.lastElementChild?.tagName !== "barline") {
|
|
|
+ const children = lastParent?.children || [];
|
|
|
+ for (let el of children) {
|
|
|
+ if (el.tagName === "barline") {
|
|
|
+ // 将结束线元素放到最后
|
|
|
+ lastParent?.appendChild(el);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ Array.from(partList).forEach((part) => {
|
|
|
+ if (part && !ids.includes(part.getAttribute("id")) ) {
|
|
|
+ part.parentNode?.removeChild(part);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
// console.log(xmlParse)
|
|
|
return new XMLSerializer().serializeToString(appoggianceFormate(xmlParse));
|
|
|
};
|
|
@@ -938,7 +1105,8 @@ export const formateTimes = (osmd: OpenSheetMusicDisplay) => {
|
|
|
// const firstTrackName = state.combinePartIndexs.length>1 ? state.partListNames[state.combinePartIndexs[0]] : state.canSelectTracks[0] || "";
|
|
|
const filterInstruments = state.osmd.Sheet.Instruments.filter(item => item.Name?.toLocaleLowerCase() !== 'common' )
|
|
|
const firstTrackName = state.combinePartIndexs.length>1 ? state.partListNames[state.combinePartIndexs[0]] : (filterInstruments[0].Name || filterInstruments[0].NameLabel.text || "");
|
|
|
- const currentTrackIndex = state.isCombineRender && state.combinePartIndexs.length > 1 ? state.combinePartIndexs[0] : 0;
|
|
|
+ // const currentTrackIndex = state.isCombineRender && state.combinePartIndexs.length > 1 ? state.combinePartIndexs[0] : 0;
|
|
|
+ const currentTrackIndex = 0;
|
|
|
while (!iterator.EndReached) {
|
|
|
// console.log({ ...iterator });
|
|
|
/** 多声轨合并显示,当前音符的时值取所有声轨中的最小值 */
|