您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Show lyrics on Lyricstraining
// ==UserScript== // @name Show lyrics LT // @namespace http://tampermonkey.net/ // @version 2025-01-04 // @description Show lyrics on Lyricstraining // @author Valerio Valletta // @match https://lyricstraining.com/* // @icon https://www.google.com/s2/favicons?sz=64&domain=lyricstraining.com // @grant none // ==/UserScript== var autoScroll = true; function setCookie(name, value, days) { var expires = ""; if (days) { var date = new Date(); date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000); expires = "; expires=" + date.toUTCString(); } document.cookie = name + "=" + (value || "") + expires + "; path=/"; } function getCookie(name) { var nameEQ = name + "="; var ca = document.cookie.split(";"); for (var i = 0; i < ca.length; i++) { var c = ca[i]; while (c.charAt(0) == " ") c = c.substring(1, c.length); if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length); } return null; } function dragElement(elmnt) { var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0; const oldBoxPos = getCookie("lyrics-box-pos"); if (oldBoxPos) { const { top, left } = JSON.parse(oldBoxPos); elmnt.style.top = top; elmnt.style.left = left; } if (document.getElementById(elmnt.id + "-header")) { // if present, the header is where you move the DIV from: document.getElementById(elmnt.id + "-header").onmousedown = dragMouseDown; } function dragMouseDown(e) { e = e || window.event; e.preventDefault(); // get the mouse cursor position at startup: pos3 = e.clientX; pos4 = e.clientY; document.onmouseup = closeDragElement; // call a function whenever the cursor moves: document.onmousemove = elementDrag; } function elementDrag(e) { e = e || window.event; e.preventDefault(); // calculate the new cursor position: pos1 = pos3 - e.clientX; pos2 = pos4 - e.clientY; pos3 = e.clientX; pos4 = e.clientY; // set the element's new position: elmnt.style.top = elmnt.offsetTop - pos2 + "px"; elmnt.style.left = elmnt.offsetLeft - pos1 + "px"; } function closeDragElement() { // stop moving when mouse button is released: const lyricsBox = document.querySelector("#lyrics-box"); const lastBoxPos = { top: lyricsBox.style.top, left: lyricsBox.style.left, }; setCookie("lyrics-box-pos", JSON.stringify(lastBoxPos)); document.onmouseup = null; document.onmousemove = null; } } function scrollParentToChild(parent, child) { // Where is the parent on page var parentRect = parent.getBoundingClientRect(); // What can you see? var parentViewableArea = { height: parent.clientHeight, width: parent.clientWidth, }; // Where is the child var childRect = child.getBoundingClientRect(); // Calculate the child's center relative to the parent's center var childCenterY = childRect.top + childRect.height / 2; var parentCenterY = parentRect.top + parentViewableArea.height / 2; // Calculate the distance to scroll var scrollY = childCenterY - parentCenterY; // Adjust the parent's scroll position parent.scrollTop += scrollY; } const createLyricsBox = () => { const lyricsBox = document.createElement("div"); lyricsBox.id = "lyrics-box"; lyricsBox.style.display = "none"; lyricsBox.style.zIndex = 50; lyricsBox.style.position = "absolute"; lyricsBox.style.right = 0; lyricsBox.style.bottom = 10; lyricsBox.style.width = "100%"; lyricsBox.style.height = "100%"; lyricsBox.style.maxHeight = "300px"; lyricsBox.style.maxWidth = "700px"; lyricsBox.style.overflowY = "scroll"; lyricsBox.style.backgroundColor = "#FFF"; lyricsBox.style.boxShadow = "rgba(0, 0, 0, 0.24) 0px 3px 8px"; lyricsBox.appendChild(createLyricsBoxHeader()); return lyricsBox; }; function createCheckbox() { // Create the input element const input = document.createElement("input"); // Set attributes input.type = "checkbox"; input.id = "switch-autoscroll"; input.style.transform = "scale(1.5)"; input.checked = true; input.onclick = toggleAutoScroll; return input; } const toggleAutoScroll = () => { autoScroll = !autoScroll; document.querySelector("#switch-autoscroll").checked = autoScroll; }; const createSwitchAutoScroll = () => { const div = document.createElement("div"); div.style.display = "flex"; div.style.justifyContent = "center"; div.style.alignItems = "center"; div.style.padding = "0.5em"; const text = document.createElement("span"); text.innerText = "autoscroll"; text.style.fontSize = "1.3em"; text.style.color = "white"; text.style.paddingRight = "0.3em"; const checkbox = createCheckbox(); div.append(text); div.appendChild(checkbox); return div; }; const createLyricsBoxHeader = () => { const header = document.createElement("div"); header.id = "lyrics-box-header"; header.style.top = 0; header.style.position = "sticky"; header.style.width = "100%"; header.style.height = "100%"; header.style.maxHeight = "50px"; header.style.backgroundColor = "royalblue"; header.style.cursor = "move"; header.style.display = "flex"; header.style.alignItems = "center"; header.style.justifyContent = "space-between"; const title = document.createElement("span"); title.innerText = "DRAG ME"; title.style.fontSize = "1.6em"; title.style.color = "white"; title.style.fontWeight = "bold"; title.style.letterSpacing = "0.3em"; title.style.padding = "0.5em"; const switchAutoScroll = createSwitchAutoScroll(); header.appendChild(title); header.appendChild(switchAutoScroll); return header; }; const createShowLyricsBtn = () => { const btn = document.createElement("button"); btn.id = "show-lyrics-btn"; btn.innerText = "SHOW LYRICS"; btn.style.fontSize = "1.5em"; btn.style.fontWeight = "bold"; btn.style.zIndex = 100; btn.style.position = "fixed"; btn.style.right = 0; btn.style.bottom = 10; btn.style.border = "2px solid royalblue"; btn.style.borderRight = "0px"; btn.style.color = "royalblue"; btn.style.background = "white"; btn.style.cursor = "pointer"; btn.style.transition = "0.5s all"; return btn; }; (function () { "use strict"; const addOptions = document.querySelector("#add-options"); const lyricsBox = createLyricsBox(); lt.game.page.lyrics.lines .map((el) => el.text) .forEach((el, i) => { const p = document.createElement("p"); p.className = "lyric-line"; p.id = `line-${i}`; p.style.fontSize = "1.5em"; p.style.color = "white"; p.style.paddingLeft = "1em"; p.innerText = el; lyricsBox.appendChild(p); }); const btn = createShowLyricsBtn(); btn.addEventListener("mouseenter", () => { let btn = document.querySelector("#show-lyrics-btn"); btn.style.fontSize = "1.6em"; }); btn.addEventListener("mouseleave", () => { let btn = document.querySelector("#show-lyrics-btn"); btn.style.fontSize = "1.5em"; }); btn.addEventListener("click", () => { let currStatus = document.querySelector("#lyrics-box").style.display; if (currStatus === "none") { document.querySelector("#lyrics-box").style.display = "block"; return; } document.querySelector("#lyrics-box").style.display = "none"; return; }); addOptions.appendChild(btn); addOptions.appendChild(lyricsBox); dragElement(lyricsBox); var trackLineVisible = new Set(); setInterval(() => { if (trackLineVisible) [hideVisibleLines()]; const lineEls = document.querySelectorAll(".lyric-line"); const currEl = lineEls[lt.game.page.playView.playLine]; if (!lineEls || !currEl) return; currEl.style.color = "green"; currEl.style.display = "block"; if (autoScroll) { scrollParentToChild(lyricsBox, currEl); } trackLineVisible.add(currEl); }, 500); const hideVisibleLines = () => { trackLineVisible.forEach((el) => { el.style.color = "black"; }); trackLineVisible.clear(); }; })();