您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Custom Nitro Type Theme w/ Font-Size, Height Sliders, and Cursor Customization
当前为
// ==UserScript== // @name Nitro Monkey | NT Theme // @version 2024-12-08 // @namespace https://gf.qytechs.cn/users/1331131-tensorflow-dvorak // @description Custom Nitro Type Theme w/ Font-Size, Height Sliders, and Cursor Customization // @author TensorFlow - Dvorak // @match *://www.nitrotype.com/* // @require https://update.gf.qytechs.cn/scripts/501960/1418069/findReact.js // @require https://update.gf.qytechs.cn/scripts/520085/1498893/Nitro%20Type%20Post%20Race%20Analysis.js // @require https://update.gf.qytechs.cn/scripts/514399/1476019/raceData.js // @require https://update.gf.qytechs.cn/scripts/515441/1476487/Nitro%20Type%20Theme%20Customizer.js // @license MIT // @grant GM_addStyle // ==/UserScript== (function () { const dynamicStyle = document.createElement("style"); document.head.appendChild(dynamicStyle); let currentCursorType = localStorage.getItem("cursorType") || "block"; let currentCursorSpeed = localStorage.getItem("cursorSpeed") || "medium"; const bgColor = localStorage.getItem("nt_bgColor") || "#060516"; const bgImage = localStorage.getItem("nt_bgImage") || ""; const textColor = localStorage.getItem("nt_textColor") || "#a6a4f7"; const cursorColor = localStorage.getItem("nt_cursorColor") || "#0075ff"; const buttonColor = localStorage.getItem("nt_buttonColor") || "#5a67d8"; const typedTextColor = localStorage.getItem("nt_typedTextColor") || "#23223b"; const cardColor = localStorage.getItem("nt_cardColor") || "#1a1a2e"; const typingAreaColor = localStorage.getItem("nt_typingAreaColor") || "#0605163d"; const typingAreaImage = localStorage.getItem("nt_typingAreaImage") || ""; function updateStyles() { dynamicStyle.innerHTML = ` ${generateCursorStyle(currentCursorType, currentCursorSpeed)} ${generateFontSizeStyle(localStorage.getItem("dashFontSize") || "40")} ${generateCustomThemeStyle(bgColor, textColor)} `; } function generateCustomThemeStyle(bgColor, textColor) { return ` .dash { background: ${typingAreaColor}; background-image: url(${typingAreaImage}); background-attachment: fixed; background-size: cover; } .dash-letter { color: ${textColor}; } .dash-letter.is-typed { color: ${typedTextColor}; } .race-results, .raceResults--default, .raceResults-rewards, .raceResults-dailyChallenges, .g-b--7of12, .footer-nav, .nav-list, .nav { background-color: ${bgColor}; } .btn--primary { background: ${buttonColor}; } .btn--primary:hover { background: ${buttonColor}d9; } `; } function lightenColor(hex, amount) { return `#${hex .replace(/^#/, "") .replace(/../g, (color) => ( "0" + Math.min(255, Math.max(0, parseInt(color, 16) + amount)).toString(16) ).slice(-2) )}`; } function generateCursorStyle(cursorType, cursorSpeed) { let cursorSize = "2px"; let cursorHeight = "1.2em"; let animationDuration = "1s"; let cursorTopOffset = "0.2em"; let cardColor = localStorage.getItem("nt_cardColor") || "#1a1a2e"; let cursorColor = localStorage.getItem("nt_cursorColor") || "#0075ff"; let cursorTransform = ""; if (cursorType === "block") { cursorSize = "0.7em"; cursorHeight = "1.1em"; cursorTopOffset = "0"; cursorColor = `${cursorColor}42`; cursorTransform = "translateY(0.3em)"; } else if (cursorType === "line") { cursorSize = "2px"; cursorHeight = "1.2em"; cursorColor = cursorColor || "#0075ff"; } else { cursorSize = "0"; } if (cursorSpeed === "slow") { animationDuration = "1.5s"; } else if (cursorSpeed === "fast") { animationDuration = "0.5s"; } return ` .dash-letter { color: #acaaff; } .dash-letter.is-waiting { position: relative; color: ${lightenColor(textColor, 60)}; background-color: #1c99f400; } .dash-letter.is-waiting::after { content: ''; display: inline-block; color: ${textColor}; width: ${cursorSize}; height: ${cursorHeight}; background-color: ${cursorColor}; animation: blink ${animationDuration} step-end infinite; position: absolute; top: ${cursorTopOffset}; left: 0; transform: ${cursorTransform}; } .season--xmaxx-2024 .racev3-ui .dash { background: ${typingAreaColor}; } .dash-letter.is-incorrect { color: red; background: #ffffff00; position: relative; } .dash-letter.is-incorrect::after { content: ''; display: inline-block; width: ${cursorSize}; height: ${cursorHeight}; background-color: rgba(255, 0, 0, 0.5); animation: blink ${animationDuration} step-end infinite; position: absolute; top: ${cursorTopOffset}; left: 0; transform: ${cursorTransform}; } @keyframes blink { 50% { opacity: 0; } } `; } function generateFontSizeStyle(fontSize) { return ` #root { background-color: ${bgColor} !important; background-image: url(${bgImage}); background-attachment: fixed; background-size: cover; } .dash-copy { font-size: ${fontSize}px !important; } #raceContainer { background-color: ${typingAreaColor} !important; } .dash-copyContainer { background: ${typingAreaColor}; background-image: url(${typingAreaImage}); background-size: cover; background-attachment: fixed; flex: 1; overflow: hidden; padding:0px; padding-left:10px; border-radius: 0px; box-shadow: none; width: 100%; display: flex; } .dash-side, .dash-actions, .dash-nitros { display: none; } .dash:before { height: min-content; } .structure-footer { display: flex; padding-top: 2rem; } .race-results { background-color: #060516; } .raceResults--default { background: #060516; } .raceResults-rewards { background: #0c0b18; } .raceResults-dailyChallenges { background: #0c0b18; } .g-b--7of12 { background: #060516; } .footer-nav { background: #0c0b18; } .nav-list { background: #0c0b18; } .nav { background: #0c0b18; border-bottom: 1px solid #14141b; } .btn--primary { background: #403dae; } .btn--primary:hover { background: #8a1bdf; } .btn--secondary { background: #5b048a; } .btn--secondary:hover { background: #8d11d0; } .gridTable--raceResults .gridTable-cell { background: #0c0b18; } .gridTable-cell { background: #0c0b18; } .dashShield-layer { display: none; } .dash-center { padding: 0px; //background: #06051687; } .nt-stats-right-section { background: #060516; } .nt-stats-daily-challenges { background: #060516; } .nt-stats-body { background: #0c0b18; } .experiment { background: ${cardColor} !important; color: ${textColor} !important; } `; } const dashElement = document.querySelector(".dash"); const container = document.querySelector(".structure-content div"); if (dashElement) { const displayContainer = document.createElement("div"); displayContainer.classList.add("nitro-monkey__settings-container"); displayContainer.style.display = "flex"; displayContainer.style.marginTop = "4rem"; displayContainer.style.fontSize = "20px"; displayContainer.style.flexWrap = "wrap"; displayContainer.style.color = textColor; displayContainer.style.background = bgColor; displayContainer.style.borderRadius = "5px"; displayContainer.style.borderRadius = "5px"; displayContainer.style.borderBottom = "2px solid #0c0b18"; displayContainer.style.justifyContent = "space-between"; displayContainer.innerHTML = ` <div class="nt-monkey__cursor-container" style="height: fit-content; padding: 1rem; background-color: ${cardColor}; border-radius: 8px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); width: auto; color: #e0e0e0; font-size: 0.9rem; margin-bottom: 1rem;"> <span id="targetWPMValue" style="display: none;">Target WPM: 100</span> <div style="margin-bottom: 0.8rem;"> <label for="targetWPM" style="margin-right: 0.5rem; color: #a0a0a0;">Target WPM:</label> <button id="decreaseWPM" class="animate--iconSlam btn btn--fw btn--gloss btn--primary dhf" style="margin-right: 0.5rem; width: 1.5rem; height: 1.5rem; font-size: 1rem; border: none; border-radius: 4px; cursor: pointer;">-</button> <input style="background: #060608; border: 1px solid #0c0b18; border-radius: 4px; color: #e0e0e0; text-align: center; width: 3rem;" type="number" id="targetWPM" min="10" max="300" value="100" readonly> <button id="increaseWPM" class="animate--iconSlam btn btn--fw btn--gloss btn--primary dhf" style="margin-left: 0.5rem; width: 1.5rem; height: 1.5rem; font-size: 1rem; border: none; border-radius: 4px; cursor: pointer;">+</button> </div> <div style="margin-bottom: 0.8rem;"> <label for="cursorType" style="margin-right: 0.5rem; color: #a0a0a0;">Cursor Type:</label> <button id="cursorTypeButton" class="animate--iconSlam btn btn--fw btn--gloss btn--primary dhf" style="height: 2rem; width: 5rem; font-size: 0.9rem; border: none; border-radius: 4px; cursor: pointer;"> ${currentCursorType.charAt(0).toUpperCase() + currentCursorType.slice(1)} </button> </div> <div> <label for="cursorSpeed" style="margin-right: 0.5rem; color: #a0a0a0;">Cursor Speed:</label> <button id="cursorSpeedButton" class="animate--iconSlam btn btn--fw btn--gloss btn--primary dhf" style="height: 2rem; width: 5rem; font-size: 0.9rem; border: none; border-radius: 4px; cursor: pointer;"> ${ currentCursorSpeed.charAt(0).toUpperCase() + currentCursorSpeed.slice(1) } </button> </div> </div> `; container.appendChild(displayContainer); const wpmDisplay = displayContainer.querySelector("div:nth-child(1)"); const targetWPMValueDisplay = displayContainer.querySelector("#targetWPMValue"); const accuracyDisplay = displayContainer.querySelector("div:nth-child(3)"); const targetWPMInput = displayContainer.querySelector("#targetWPM"); const increaseWPMButton = displayContainer.querySelector("#increaseWPM"); const decreaseWPMButton = displayContainer.querySelector("#decreaseWPM"); const cursorTypeButton = displayContainer.querySelector("#cursorTypeButton"); const cursorSpeedButton = displayContainer.querySelector("#cursorSpeedButton"); const savedTargetWPM = localStorage.getItem("targetWPM") || "100"; targetWPMInput.value = savedTargetWPM; targetWPMValueDisplay.textContent = `Target WPM: ${savedTargetWPM}`; function updateTargetWPM(value) { const targetWPM = Math.max(50, Math.min(200, parseInt(value, 10))); targetWPMInput.value = targetWPM; targetWPMValueDisplay.textContent = `Target WPM: ${targetWPM}`; localStorage.setItem("targetWPM", targetWPM); } increaseWPMButton.addEventListener("click", function () { updateTargetWPM(parseInt(targetWPMInput.value, 10) + 5); }); decreaseWPMButton.addEventListener("click", function () { updateTargetWPM(parseInt(targetWPMInput.value, 10) - 5); }); const cursorTypes = ["none", "block", "line"]; const cursorSpeeds = ["slow", "medium", "fast"]; cursorTypeButton.addEventListener("click", function () { let currentIndex = cursorTypes.indexOf(currentCursorType); currentCursorType = cursorTypes[(currentIndex + 1) % cursorTypes.length]; cursorTypeButton.textContent = currentCursorType.charAt(0).toUpperCase() + currentCursorType.slice(1); localStorage.setItem("cursorType", currentCursorType); updateStyles(); }); cursorSpeedButton.addEventListener("click", function () { let currentIndex = cursorSpeeds.indexOf(currentCursorSpeed); currentCursorSpeed = cursorSpeeds[(currentIndex + 1) % cursorSpeeds.length]; cursorSpeedButton.textContent = currentCursorSpeed.charAt(0).toUpperCase() + currentCursorSpeed.slice(1); localStorage.setItem("cursorSpeed", currentCursorSpeed); updateStyles(); }); const sliderContainer = document.createElement("div"); sliderContainer.className = "sliderContainer"; sliderContainer.style.padding = "10px"; sliderContainer.style.backgroundColor = cardColor; sliderContainer.style.borderRadius = "8px"; sliderContainer.style.boxShadow = "0 2px 8px rgba(0, 0, 0, 0.15)"; sliderContainer.style.marginBottom = "1rem"; sliderContainer.style.color = "#e0e0e0"; sliderContainer.style.fontSize = "0.9rem"; sliderContainer.style.width = "20rem"; sliderContainer.style.height = "fit-content"; // Height slider const heightContainer = document.createElement("div"); heightContainer.style.marginBottom = "10px"; const heightLabel = document.createElement("label"); heightLabel.textContent = "Adjust Height:"; heightLabel.style.color = "#5d5aec"; heightLabel.style.display = "block"; heightLabel.style.marginBottom = "5px"; const heightSlider = document.createElement("input"); heightSlider.type = "range"; heightSlider.min = "100"; heightSlider.max = "1000"; const savedHeight = localStorage.getItem("dashHeight") || "500"; dashElement.style.height = `${savedHeight}px`; heightSlider.value = savedHeight; heightSlider.style.width = "100%"; heightSlider.style.cursor = "pointer"; heightContainer.appendChild(heightLabel); heightContainer.appendChild(heightSlider); sliderContainer.appendChild(heightContainer); heightSlider.addEventListener("input", function () { const heightValue = heightSlider.value; dashElement.style.height = `${heightValue}px`; localStorage.setItem("dashHeight", heightValue); }); // Font size slider const fontSizeContainer = document.createElement("div"); fontSizeContainer.style.marginBottom = "10px"; const fontSizeLabel = document.createElement("label"); fontSizeLabel.textContent = "Adjust Font Size:"; fontSizeLabel.style.color = "#5d5aec"; fontSizeLabel.style.display = "block"; fontSizeLabel.style.marginBottom = "5px"; const fontSizeSlider = document.createElement("input"); fontSizeSlider.type = "range"; fontSizeSlider.min = "20"; fontSizeSlider.max = "80"; fontSizeSlider.value = localStorage.getItem("dashFontSize") || "40"; fontSizeSlider.style.width = "100%"; fontSizeSlider.style.cursor = "pointer"; fontSizeContainer.appendChild(fontSizeLabel); fontSizeContainer.appendChild(fontSizeSlider); sliderContainer.appendChild(fontSizeContainer); displayContainer.appendChild(sliderContainer); fontSizeSlider.addEventListener("input", function () { const newFontSize = fontSizeSlider.value; localStorage.setItem("dashFontSize", newFontSize); updateStyles(); }); updateStyles(); } setInterval(() => { const experimentDiv = document.querySelector(".experiment"); if (experimentDiv && container) { const experimentParent = experimentDiv.parentElement; container.parentElement.appendChild(experimentDiv); } }, 500); // Retain scroll position window.addEventListener("beforeunload", () => { localStorage.setItem("scrollPosition", window.scrollY); }); window.addEventListener("load", () => { setTimeout(() => { const scrollPosition = localStorage.getItem("scrollPosition"); if (scrollPosition) { window.scrollTo(0, parseInt(scrollPosition, 10)); } }, 1000); }); // Fix stickers? setInterval(() => { const raceChatElement = document.querySelector(".raceChat"); const heightValue = localStorage.getItem("dashHeight") || "500"; if (raceChatElement) { raceChatElement.style.bottom = `calc(${parseInt( heightValue )}px + 2.5rem)`; } }, 500); })(); (function () { let startTime = null; let intervalId = null; let peakWPM = 0; let skippedChars = 0; let totalIncorrectTypedCharacters = 0; const trackedIncorrectLetters = new Set(); let totalCharactersInRace = 0; let errorsAllowed = 0; function addWPMDrawer() { const bgColor = localStorage.getItem("nt_bgColor") || "#060516"; const textColor = localStorage.getItem("nt_textColor") || "#6864f6"; const dashElement = document.querySelector(".dash"); const cardColor = localStorage.getItem("nt_cardColor") || "#1a1a2e"; if (dashElement) { const displayContainer = document.createElement("div"); displayContainer.classList.add("nitro-monkey__wpm-container"); displayContainer.style.display = "flex"; displayContainer.style.gap = "2rem"; displayContainer.style.fontSize = "25px"; displayContainer.style.width = "100%"; displayContainer.style.color = textColor; displayContainer.style.height = "2.5rem"; displayContainer.style.background = bgColor; displayContainer.style.justifyContent = "space-between"; displayContainer.style.borderBottom = "2px solid #0c0b18"; displayContainer.innerHTML = ` <div>WPM: <span id="wpmValue">0</span></div> <div>Accuracy: <span id="accuracyValue">100%</span></div> <div>Peak WPM: <span id="peakWpmValue">0</span></div> <div>Errors Allowed: <span id="errorsAllowedValue">0</span></div> `; dashElement.parentNode.insertBefore(displayContainer, dashElement); } } function calculateWPM(totalCharacters, timeInSeconds) { const wordsTyped = totalCharacters / 5; const WPM = (wordsTyped * 60) / timeInSeconds; return WPM; } function calculateErrorsAllowed(totalCharacters) { return Math.floor(0.04 * (totalCharacters - skippedChars)); } function getCorrectlyTypedCharacterCount() { let correctLetters = document.querySelectorAll( ".dash-letter.is-correct.is-typed" )?.length; const skippedWord = Array.from( document.querySelectorAll(".dash-letter.is-correct.is-typed") ); const nitorUsed = document.querySelector(".dash-nitro.is-used"); if (nitorUsed && skippedWord) { correctLetters = correctLetters - skippedWord.pop().parentNode.children.length; if (skippedChars === 0) { skippedChars = skippedWord.pop().parentNode.children.length; } } return correctLetters - skippedChars; } function detectMistakes() { const incorrectLetters = document.querySelectorAll( ".dash-letter.is-incorrect" ); incorrectLetters.forEach((letter) => { if (!trackedIncorrectLetters.has(letter)) { totalIncorrectTypedCharacters += 1; trackedIncorrectLetters.add(letter); errorsAllowed = Math.max(0, errorsAllowed - 1); document.getElementById("errorsAllowedValue").textContent = errorsAllowed; } }); } function getTotalTypedCharacterCount() { const typedLetters = document.querySelectorAll(".dash-letter.is-typed"); return typedLetters.length - skippedChars; } function getTotalCharacters() { const totalLetters = document.querySelectorAll(".dash-letter").length; return totalLetters - 1; } function calculateAccuracy(totalCharacters, incorrectCharacters) { const totalTyped = totalCharacters - incorrectCharacters; const total = totalCharacters; return (totalTyped / total) * 100; } const getTypedCharacterCount = () => { return document.querySelectorAll(".dash-letter.is-correct.is-typed") ?.length; }; function updateWPM() { if (!startTime) return; const currentTime = new Date(); const elapsedTime = (currentTime - startTime) / 1000; const typedCharacters = getTypedCharacterCount(); const correctlyTypedCharacters = getCorrectlyTypedCharacterCount(); detectMistakes(); const wpm = calculateWPM(correctlyTypedCharacters, elapsedTime); document.getElementById("wpmValue").textContent = Math.round(wpm); if (wpm > peakWPM) { peakWPM = wpm; document.getElementById("peakWpmValue").textContent = Math.round(peakWPM); } const accuracy = calculateAccuracy( correctlyTypedCharacters, totalIncorrectTypedCharacters ); document.getElementById("accuracyValue").textContent = `${accuracy.toFixed( 2 )}%`; if (typedCharacters >= totalCharactersInRace) { createPostRaceInfo(); stopWPMTimer(); } fetchStats(); } function createPostRaceInfo() { const wpmContainer = document.querySelector(".nitro-monkey__wpm-container"); if (wpmContainer) { wpmContainer.style.bottom = "-3rem"; wpmContainer.style.position = "absolute"; } } function startWPMTimer() { if (!startTime) { startTime = new Date(); peakWPM = 0; totalIncorrectTypedCharacters = 0; trackedIncorrectLetters.clear(); totalCharactersInRace = getTotalCharacters(); errorsAllowed = calculateErrorsAllowed(totalCharactersInRace); document.getElementById("errorsAllowedValue").textContent = errorsAllowed; intervalId = setInterval(updateWPM, 100); } } function stopWPMTimer() { if (intervalId) { clearInterval(intervalId); } } function getRaceServer() { const raceContainer = document.getElementById("raceContainer"); if (raceContainer) { const raceObj = findReact(raceContainer); return raceObj ? raceObj.server : null; } return null; } const fetchStats = () => { const wpmElement = document.querySelector("#wpmValue"); const accuracyElement = document.querySelector("#accuracyValue"); const targetWPM = parseInt(localStorage.getItem("targetWPM"), 10) || 100; const green = "#00FF7F"; const yellow = "#FFD700"; const red = "red"; if (wpmElement) { const wpmValue = parseInt(wpmElement.textContent, 10) || 0; if (wpmValue >= targetWPM - 5 && wpmValue <= targetWPM + 5) { wpmElement.style.color = green; } else if (wpmValue < targetWPM - 10) { wpmElement.style.color = red; } else if (wpmValue < targetWPM - 5) { wpmElement.style.color = yellow; } else if (wpmValue > targetWPM + 5) { wpmElement.style.color = "blue"; } } if (accuracyElement) { const accuracyValue = parseFloat(accuracyElement.textContent) || 0; if (accuracyValue < 94) { accuracyElement.style.color = red; } else if (accuracyValue >= 94 && accuracyValue < 96) { accuracyElement.style.color = yellow; } else { accuracyElement.style.color = green; } } }; function monitorServerEvents() { const server = getRaceServer(); if (!server) { setTimeout(monitorServerEvents, 1000); return; } server.on("status", (e) => { if (e.status === "racing") { startWPMTimer(); } else if (e.status === "complete") { stopWPMTimer(); } }); } function initializeScript() { addWPMDrawer(); monitorServerEvents(); } window.addEventListener("load", () => { setTimeout(() => { initializeScript(); }, 1000); }); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址