const controls = document.querySelector(".controls"); const song = document.querySelector("iframe.song").contentWindow; // Autoscroll let scroll; let scrollTimeout = 60; const minTimeout = 10; const maxTimeout = 120; const scrollIncrement = 20; function pageScroll() { song.scrollBy(0, 1); scroll = setTimeout(pageScroll, scrollTimeout); } function updateScrollSpeed() { if (controls.querySelector("#autoscroll").classList.contains("active")) { clearTimeout(scroll); scroll = setTimeout(pageScroll, scrollTimeout); } } controls.querySelector("#autoscroll-increase").addEventListener("click", () => { scrollTimeout = Math.max(minTimeout, scrollTimeout - scrollIncrement); updateScrollSpeed(); }); controls.querySelector("#autoscroll-decrease").addEventListener("click", () => { scrollTimeout = Math.min(maxTimeout, scrollTimeout + scrollIncrement); updateScrollSpeed(); }); controls.querySelector("#autoscroll").addEventListener("click", function() { this.classList.toggle("active"); if (this.classList.contains("active")) { pageScroll(); } else { clearTimeout(scroll); } }); // Scaling function pageScale(value) { if (value === 0) { song.document.body.style.transform = "scale(1)"; return; } const currentScale = parseFloat(song.document.body.style.transform.split("scale(")[1]) || 1; song.document.body.style.transform = "scale(" + (currentScale + value) + ")"; } controls .querySelector("#font-size-increase") .addEventListener("click", () => pageScale(0.1)); controls .querySelector("#font-size-decrease") .addEventListener("click", () => pageScale(-0.1)); controls .querySelector("#font-size-reset") .addEventListener("click", () => pageScale(0)); // Display the controls on JS-enabled browsers window.addEventListener("load", () => (controls.classList.remove = "hidden")); // Transpose let transCounter = 0; const chords = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B",]; const chordsFlat = ["C", "Db", "D", "Eb", "E", "F", "Gb", "G", "Ab", "A", "Bb", "B",]; function transposeChord(chord, steps) { let useFlats = chord.includes("b"); let chordList = useFlats ? chordsFlat : chords; let match = chord.match(/^([A-G][#b]?)/); if (!match) return chord; let root = match[1]; let index = chordList.indexOf(root); if (index === -1) return chord; let newIndex = (index + steps + 12) % 12; let transposedRoot = chordList[newIndex]; return transposedRoot + chord.slice(root.length); } function transposeSong(steps) { const iframe = document.querySelector("iframe.song"); const innerDoc = iframe.contentDocument || iframe.contentWindow.document; innerDoc.querySelectorAll("tr.chords td").forEach((td) => { let chord = td.textContent.trim(); if (chord) { td.textContent = transposeChord(chord, steps); } }); } document.querySelector("#transpose-decrease").addEventListener("click", () => { transposeSong(-1); transCounter -= 1 }); document.querySelector("#transpose-increase").addEventListener("click", () => { transposeSong(1); transCounter += 1 }); document.querySelector("#transpose-reset").addEventListener("click", () => { transposeSong(transCounter * -1); transCounter = 0; });