Skip to content

Commit

Permalink
update liquifier
Browse files Browse the repository at this point in the history
  • Loading branch information
kepper committed Oct 7, 2024
1 parent f32c061 commit 95d6474
Show file tree
Hide file tree
Showing 3 changed files with 178 additions and 15 deletions.
49 changes: 35 additions & 14 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import { JSDOM } from 'jsdom'
import createVerovioModule from 'verovio/wasm'
import { VerovioToolkit } from 'verovio/esm'

import { walk, getFilesObject, fetchData, writeData } from './src/filehandler.js'
import { dir } from './src/config.mjs'
import { prepareDtForRendering } from './src/diplomaticTranscripts.js'
import { prepareDtForRendering, finalizeDiploTrans } from './src/diplomaticTranscripts.js'
import { prepareAtForRendering } from './src/annotatedTranscripts.js'
import createVerovioModule from 'verovio/wasm'
import { VerovioToolkit } from 'verovio/esm'
import { generateFluidTranscription } from './src/fluidTranscripts.js'

import { renderData } from './src/verovioHandler.js'

const { DOMParser } = new JSDOM().window
const dom = new JSDOM(`<!DOCTYPE html><p>Hello world</p>`)

const main = async () => {
const VerovioModule = await createVerovioModule()
Expand Down Expand Up @@ -49,18 +54,34 @@ const main = async () => {
main()

const handleData = async (data, triple, verovio) => {
// const dtOutDom = prepareDtForRendering(data)
// const atOutDom = prepareAtForRendering(data, dtOutDom)

// const dtSvgString = renderData(dtOutDom, verovio)
// const atSvgString = renderData(atOutDom, verovio)

const dtSvgPath = triple.dt.replace('.xml', '.svg').replace('data/', 'cache/')
const atSvgPath = triple.at.replace('.xml', '.svg').replace('data/', 'cache/')
// const ftSvgPath = triple.at.replace('.xml', '.svg').replace('data/', 'cache/').replace('/annotatedTranscripts/', '/fluidTranscripts/')
console.log('Finished Rendering for ' + dtSvgPath)
const ftSvgPath = triple.at.replace('_at.xml', '_ft.svg').replace('data/', 'cache/').replace('/annotatedTranscripts/', '/fluidTranscripts/')

writeData('test diplomatic transcription', dtSvgPath)
writeData('test annotated transcription', atSvgPath)
// console.log(dtSvgString)
try {
const dtOutDom = prepareDtForRendering(data)
const dtSvgString = renderData(dtOutDom, verovio)
const finalDtDom = finalizeDiploTrans(dtSvgString)

const atOutDom = prepareAtForRendering(data, dtOutDom)
const atSvgString = renderData(atOutDom, verovio)

const parser = new DOMParser()
const dtSvgDom = parser.parseFromString(dtSvgString, 'image/svg+xml')
const atSvgDom = parser.parseFromString(atSvgString, 'image/svg+xml')

const ftSvgDom = generateFluidTranscription({ atSvgDom, dtSvgDom, atOutDom, dtOutDom })

// const ftSvgPath = triple.at.replace('.xml', '.svg').replace('data/', 'cache/').replace('/annotatedTranscripts/', '/fluidTranscripts/')
console.log('Finished Rendering for ' + dtSvgPath)

const serializer = new dom.window.XMLSerializer()

writeData(serializer.serializeToString(finalDtDom), dtSvgPath)
writeData(atSvgString, atSvgPath)
writeData(serializer.serializeToString(ftSvgDom), ftSvgPath)
// console.log(dtSvgString)
} catch (err) {
console.error('[ERROR]: Unable to process files for ' + dtSvgPath + ': ' + err + '\n\n')
}
}
22 changes: 21 additions & 1 deletion src/diplomaticTranscripts.js
Original file line number Diff line number Diff line change
Expand Up @@ -205,4 +205,24 @@ export const prepareDtForRendering = ({ dtDom, atDom, sourceDom }) => {
console.error('Error in prepareDtForRendering: ' + err, err)
}
return outDom
}
}

export const finalizeDiploTrans = (svgString) => {
const dtSvgDom = new DOMParser().parseFromString(svgString, 'image/svg+xml')

dtSvgDom.querySelectorAll('.staff:not(.bounding-box)').forEach(staff => {
const rotate = staff.getAttribute('data-rotate')
const height = staff.getAttribute('data-height')
const topLineCoordinates = staff.querySelector('path').getAttribute('d').split(' ')
const x = topLineCoordinates[0].substring(1)
const y = topLineCoordinates[1]
staff.style.transform = 'rotate(' + rotate + 'deg) scaleY(' + height + ')'
staff.style.transformOrigin = x + 'px ' + y + 'px'
})

dtSvgDom.querySelectorAll('.measure:not(.bounding-box)').forEach(measure => {
measure.querySelector('.barLine').style.display = 'none'
})

return dtSvgDom
}
122 changes: 122 additions & 0 deletions src/fluidTranscripts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import { appendNewElement } from "./utils.js"
import { JSDOM } from 'jsdom'
const { DOMParser } = new JSDOM().window
const dom = new JSDOM(`<!DOCTYPE html><p>Hello world</p>`)

export const generateFluidTranscription = ({ atSvgDom, dtSvgDom, atOutDom, dtOutDom }) => {
const supportedElements = ['note']

const ftSvgDom = atSvgDom.cloneNode(true)

supportedElements.forEach(name => {
atOutDom.querySelectorAll(name).forEach(atNode => {
if (atNode.hasAttribute('corresp')) {
const correspID = atNode.getAttribute('corresp').split('#')[1]
const dtSvgNode = dtSvgDom.querySelector('*[data-id="' + correspID + '"]')
const ftSvgNode = ftSvgDom.querySelector('*[data-id="' + atNode.getAttribute('xml:id') + '"]')
generateAnimation(name, ftSvgNode, dtSvgNode)
} else {
const ftSvgNode = ftSvgDom.querySelector('*[data-id="' + atNode.getAttribute('xml:id') + '"]')
generateHideAnimation(ftSvgNode)
}
})
})

return ftSvgDom
}

const generateHideAnimation = (node) => {
const hideAnim = appendNewElement(node, 'animate', 'http://www.w3.org/2000/svg')
hideAnim.setAttribute('attributeName', 'opacity')
hideAnim.setAttribute('values', '0;1;0')
hideAnim.setAttribute('dur', '3s')
hideAnim.setAttribute('repeatCount', 'indefinite')
}

const generateAnimation = (name, ftSvgNode, dtSvgNode) => {
if (name === 'note') {
generateAnimation_note(ftSvgNode, dtSvgNode)
} else {
console.warn('Unable to animate element ' + name)
}
}

const generateAnimation_note = (atSvgNode, dtSvgNode) => {
try {
// notehead animation
const atHead = atSvgNode.querySelector('.notehead use')
const atHeadX = parseFloat(atHead.getAttribute('x'))
const atHeadY = parseFloat(atHead.getAttribute('y'))
const dtHead = dtSvgNode.querySelector('.notehead use')
const dtHeadX = parseFloat(dtHead.getAttribute('x'))
const dtHeadY = parseFloat(dtHead.getAttribute('y'))

const headAnim = appendNewElement(atHead, 'animate', 'http://www.w3.org/2000/svg')
headAnim.setAttribute('attributeName', 'x')
headAnim.setAttribute('values', dtHeadX + ';' + atHeadX + ';' + dtHeadX)
headAnim.setAttribute('dur', '3s')
headAnim.setAttribute('repeatCount', 'indefinite')

// TODO: animate y as well, based on offsets…

// stem animation
const atStemNode = atSvgNode.querySelector('.stem path')
if (atStemNode) {
const atStem = atSvgNode.querySelector('.stem path')?.getAttribute('d')
const dtStem = dtSvgNode.querySelector('.stem path')?.getAttribute('d')
const atStem_x = atStem.split(' ')[0]
const atStem_y = atStem.split(' ')[1]
const atStem_l = parseFloat(atStem.split(' ')[1]) - parseFloat(atStem.split(' ')[3])
const dtStem_x = dtStem.split(' ')[0]
const dtStem_l = parseFloat(dtStem.split(' ')[1]) - parseFloat(dtStem.split(' ')[3])

const dtStemNew = dtStem_x + ' ' + atStem_y + ' ' + dtStem.split(' ')[2] + ' ' + (parseFloat(atStem_y) - dtStem_l)

const stemAnim = appendNewElement(atStemNode, 'animate', 'http://www.w3.org/2000/svg')
stemAnim.setAttribute('attributeName', 'd')
stemAnim.setAttribute('attributeType', 'XML')
stemAnim.setAttribute('values', dtStemNew + '; ' + atStem + '; ' + dtStemNew)
stemAnim.setAttribute('dur', '3s')
stemAnim.setAttribute('repeatCount', 'indefinite')

const atFlagNode = atSvgNode.querySelector('.flag use')
if (atFlagNode) {
const dtFlagNode = dtSvgNode.querySelector('.flag use')
const atX = atFlagNode.getAttribute('x')
const atY = atFlagNode.getAttribute('y')
console.log('dtStem_x: ', parseInt(dtStem_x), parseInt(dtStem_x) - 7)
const dtX = parseFloat(dtStem_x.substring(1)) - 7
const dtY = parseFloat(atStem_y) - dtStem_l

const flagAnimX = appendNewElement(atFlagNode, 'animate', 'http://www.w3.org/2000/svg')
flagAnimX.setAttribute('attributeName', 'x')
flagAnimX.setAttribute('values', dtX + ';' + atX + ';' + dtX)
flagAnimX.setAttribute('dur', '3s')
flagAnimX.setAttribute('repeatCount', 'indefinite')

const flagAnimY = appendNewElement(atFlagNode, 'animate', 'http://www.w3.org/2000/svg')
flagAnimY.setAttribute('attributeName', 'y')
flagAnimY.setAttribute('values', dtY + ';' + atY + ';' + dtY)
flagAnimY.setAttribute('dur', '3s')
flagAnimY.setAttribute('repeatCount', 'indefinite')
// const dtY =
}
}

// flag animation
/*
x="3382"
y="1440" => equals atStem.split(' ')[3]
*/

/*
<animate
attributeName="rx"
values="0;5;0"
dur="10s"
repeatCount="indefinite" />
*/
} catch(err) {
console.warn('Error in generateAnimation_note: ' + err, err)
}
}

0 comments on commit 95d6474

Please sign in to comment.