Lyrics Page Layout Similar to ProPresenter7 Stage Layout

Oh, that’s not looking good! Does this version work better?

import { textFit } from "./textFit.js";

let observer;
let interval;

const init = () => {
  const target = document.querySelector(".lyrics-page .lyrics div");

  if (!target) {
    console.log("This doesn't seem to be a lyrics page");
    return;
  }

  const callback = async (_a, _b, options) => {
    const lyrics = document.querySelectorAll(
      ".lyrics-line span:not(.text-fit)"
    );

    lyrics.forEach((el) => {
      el.style.display = "block";
      el.style.width = el.parentElement.clientWidth + "px";
      el.style.height = el.parentElement.clientHeight + "px";
      el.classList.add("text-fit");
    });

    // maxFontSize can be adjusted if the font becomes too large
    textFit(lyrics, { multiLine: true, maxFontSize: 300, ...options });
  };

  observer = new MutationObserver(callback);
  observer.observe(target, { childList: true });
  callback();

  // Since AbleSet 2.4.0, you have access to real-time updates
  ableset.getSocket("lyrics").on("tracksUpdated", () => {
    setTimeout(callback, 1000);
  });

  if (interval) {
    clearInterval(interval);
  }

  // If a line is replaced, re-fit its text.
  // This is a bit of a brute-force approach that just runs the fitting
  // process every second and ignores lines that have already been adjusted.
  interval = setInterval(() => callback(null, null, { reProcess: false }), 1000);
};

// Keep track of the current URL so we can run
// the script again when navigating to a lyrics page
let lastLocation = "";

setInterval(() => {
  if (location.href !== lastLocation && location.href.includes("/lyrics")) {
    lastLocation = location.href;
    observer?.disconnect();
    init();
  }
}, 1000);
1 Like