|  | @@ -155,22 +155,23 @@ export default defineComponent({
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      onMounted(async () => {
 |  |      onMounted(async () => {
 | 
											
												
													
														|  |        if (rendered.value) return
 |  |        if (rendered.value) return
 | 
											
												
													
														|  | -      if (!musicInfo.musicSvg || props.isSoundEffect) {
 |  | 
 | 
											
												
													
														|  | -        setOsdm()
 |  | 
 | 
											
												
													
														|  | -        return
 |  | 
 | 
											
												
													
														|  | -      }
 |  | 
 | 
											
												
													
														|  | -      if (SettingState.sett.type === 'staff') {
 |  | 
 | 
											
												
													
														|  | -        renderData.value = musicInfo.musicSvg?.staff
 |  | 
 | 
											
												
													
														|  | -      } else {
 |  | 
 | 
											
												
													
														|  | -        //是否固定调
 |  | 
 | 
											
												
													
														|  | -        renderData.value = SettingState.sett.keySignature ? musicInfo.musicSvg?.fixedTone : musicInfo.musicSvg?.firstTone
 |  | 
 | 
											
												
													
														|  | -      }
 |  | 
 | 
											
												
													
														|  | -      // console.log("🚀 ~ renderData:", renderData)
 |  | 
 | 
											
												
													
														|  | -      if (renderData.value && renderData.value.json) {
 |  | 
 | 
											
												
													
														|  | -        productJsonAndSvg(renderData.value)
 |  | 
 | 
											
												
													
														|  | -      } else {
 |  | 
 | 
											
												
													
														|  | -        setOsdm()
 |  | 
 | 
											
												
													
														|  | -      }
 |  | 
 | 
											
												
													
														|  | 
 |  | +      setOsdm()
 | 
											
												
													
														|  | 
 |  | +      // 暂时不使用缓存
 | 
											
												
													
														|  | 
 |  | +      // if (!musicInfo.musicSvg || props.isSoundEffect) {
 | 
											
												
													
														|  | 
 |  | +      //   return
 | 
											
												
													
														|  | 
 |  | +      // }
 | 
											
												
													
														|  | 
 |  | +      // if (SettingState.sett.type === 'staff') {
 | 
											
												
													
														|  | 
 |  | +      //   renderData.value = musicInfo.musicSvg?.staff
 | 
											
												
													
														|  | 
 |  | +      // } else {
 | 
											
												
													
														|  | 
 |  | +      //   //是否固定调
 | 
											
												
													
														|  | 
 |  | +      //   renderData.value = SettingState.sett.keySignature ? musicInfo.musicSvg?.fixedTone : musicInfo.musicSvg?.firstTone
 | 
											
												
													
														|  | 
 |  | +      // }
 | 
											
												
													
														|  | 
 |  | +      // // console.log("🚀 ~ renderData:", renderData)
 | 
											
												
													
														|  | 
 |  | +      // if (renderData.value && renderData.value.json) {
 | 
											
												
													
														|  | 
 |  | +      //   productJsonAndSvg(renderData.value)
 | 
											
												
													
														|  | 
 |  | +      // } else {
 | 
											
												
													
														|  | 
 |  | +      //   setOsdm()
 | 
											
												
													
														|  | 
 |  | +      // }
 | 
											
												
													
														|  |      })
 |  |      })
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      onUnmounted(() => {
 |  |      onUnmounted(() => {
 | 
											
										
											
												
													
														|  | @@ -214,7 +215,6 @@ export default defineComponent({
 | 
											
												
													
														|  |              await useOsmdLoader(osmd.value, renderScore)
 |  |              await useOsmdLoader(osmd.value, renderScore)
 | 
											
												
													
														|  |              emit('rerender', osmd.value)
 |  |              emit('rerender', osmd.value)
 | 
											
												
													
														|  |              event.emit('loaded')
 |  |              event.emit('loaded')
 | 
											
												
													
														|  | -            // resetFormate()
 |  | 
 | 
											
												
													
														|  |            } catch (error) {
 |  |            } catch (error) {
 | 
											
												
													
														|  |              console.error(error)
 |  |              console.error(error)
 | 
											
												
													
														|  |              emit('renderError')
 |  |              emit('renderError')
 | 
											
										
											
												
													
														|  | @@ -234,367 +234,6 @@ export default defineComponent({
 | 
											
												
													
														|  |        }
 |  |        }
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -    const resetFormate = () => {
 |  | 
 | 
											
												
													
														|  | -      const stafflines: SVGAElement[] = Array.from((container.value as HTMLElement).querySelectorAll('.staffline'))
 |  | 
 | 
											
												
													
														|  | -      const baseStep = 4 // 两个元素相间,的间距
 |  | 
 | 
											
												
													
														|  | -      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 repetWord = ['To Coda', 'D.S. al Coda', 'Coda']
 |  | 
 | 
											
												
													
														|  | -        texts
 |  | 
 | 
											
												
													
														|  | -          .filter((n) => repetWord.includes(n.textContent || ''))
 |  | 
 | 
											
												
													
														|  | -          .forEach((t) => {
 |  | 
 | 
											
												
													
														|  | -            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)
 |  | 
 | 
											
												
													
														|  | -                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)
 |  | 
 | 
											
												
													
														|  | -                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)`
 |  | 
 | 
											
												
													
														|  | -                }
 |  | 
 | 
											
												
													
														|  | -              }
 |  | 
 | 
											
												
													
														|  | -            })
 |  | 
 | 
											
												
													
														|  | -          })
 |  | 
 | 
											
												
													
														|  | -        // 文字方框和飞线碰撞
 |  | 
 | 
											
												
													
														|  | -        // console.log(staveSection, 'staveSection out')
 |  | 
 | 
											
												
													
														|  | -        staveSection.forEach((t) => {
 |  | 
 | 
											
												
													
														|  | -          let shift_y = 0
 |  | 
 | 
											
												
													
														|  | -          ;[...vfcurve, ...vfties, ...vfvoices].forEach((curve) => {
 |  | 
 | 
											
												
													
														|  | -            const result = collisionDetection(t, curve)
 |  | 
 | 
											
												
													
														|  | -            // console.log(result, 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.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)
 |  | 
 | 
											
												
													
														|  | -            _vftexts.push(vftext as SVGAElement)
 |  | 
 | 
											
												
													
														|  | -          }
 |  | 
 | 
											
												
													
														|  | -        })
 |  | 
 | 
											
												
													
														|  | -        if (maxY !== 0 && _vftexts.length > 1) {
 |  | 
 | 
											
												
													
														|  | -          _vftexts.forEach((vftext) => {
 |  | 
 | 
											
												
													
														|  | -            vftext.setAttribute('y', 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)
 |  | 
 | 
											
												
													
														|  | -            }
 |  | 
 | 
											
												
													
														|  | -          })
 |  | 
 | 
											
												
													
														|  | -        })
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -        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 + '')
 |  | 
 | 
											
												
													
														|  | -                }
 |  | 
 | 
											
												
													
														|  | -              } 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 + '')
 |  | 
 | 
											
												
													
														|  | -                }
 |  | 
 | 
											
												
													
														|  | -              }
 |  | 
 | 
											
												
													
														|  | -            }
 |  | 
 | 
											
												
													
														|  | -          })
 |  | 
 | 
											
												
													
														|  | -        })
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -        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'))) + '')
 |  | 
 | 
											
												
													
														|  | -            }
 |  | 
 | 
											
												
													
														|  | -          })
 |  | 
 | 
											
												
													
														|  | -        })
 |  | 
 | 
											
												
													
														|  | -        // 如果渐弱渐强有平行的文字
 |  | 
 | 
											
												
													
														|  | -        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 + '')
 |  | 
 | 
											
												
													
														|  | -              }
 |  | 
 | 
											
												
													
														|  | -            } else if (result.x2 > result.x1 + result.w1) {
 |  | 
 | 
											
												
													
														|  | -              // 右
 |  | 
 | 
											
												
													
														|  | -              if (Math.abs(result.y2 - result.y1) > 10) {
 |  | 
 | 
											
												
													
														|  | -                text.setAttribute('y', 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 + '')
 |  | 
 | 
											
												
													
														|  | -                }
 |  | 
 | 
											
												
													
														|  | -              } 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 + '')
 |  | 
 | 
											
												
													
														|  | -                }
 |  | 
 | 
											
												
													
														|  | -              }
 |  | 
 | 
											
												
													
														|  | -            }
 |  | 
 | 
											
												
													
														|  | -          } 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 + '')
 |  | 
 | 
											
												
													
														|  | -            }
 |  | 
 | 
											
												
													
														|  | -            text2.setAttribute('x', result2.x1 + result2.w1 + 5 + '')
 |  | 
 | 
											
												
													
														|  | -            if (Math.abs(result2.y2 - result2.y1) > 10) {
 |  | 
 | 
											
												
													
														|  | -              text2.setAttribute('y', 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 + '')
 |  | 
 | 
											
												
													
														|  | -                }
 |  | 
 | 
											
												
													
														|  | -              } else {
 |  | 
 | 
											
												
													
														|  | -                const result = collisionDetection(vftext as SVGAElement, text as SVGAElement)
 |  | 
 | 
											
												
													
														|  | -                if (result.isCollision) {
 |  | 
 | 
											
												
													
														|  | -                  text.setAttribute('y', result.y1 + result.h1 + result.h2 + '')
 |  | 
 | 
											
												
													
														|  | -                }
 |  | 
 | 
											
												
													
														|  | -              }
 |  | 
 | 
											
												
													
														|  | -            }
 |  | 
 | 
											
												
													
														|  | -          })
 |  | 
 | 
											
												
													
														|  | -        })
 |  | 
 | 
											
												
													
														|  | -      }
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -      setTimeout(() => resetGlobalText())
 |  | 
 | 
											
												
													
														|  | -    }
 |  | 
 | 
											
												
													
														|  | -    // 技巧文本
 |  | 
 | 
											
												
													
														|  | -    const resetGlobalText = () => {
 |  | 
 | 
											
												
													
														|  | -      if (!container.value) return
 |  | 
 | 
											
												
													
														|  | -      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,
 |  | 
 | 
											
												
													
														|  | -        }
 |  | 
 | 
											
												
													
														|  | -      }
 |  | 
 | 
											
												
													
														|  | -    }
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  |      expose({
 |  |      expose({
 | 
											
												
													
														|  |        setRender,
 |  |        setRender,
 | 
											
												
													
														|  |        reRender,
 |  |        reRender,
 |