Nitro Type Theme Customizer

Theme Customizer

This script should not be not be installed directly. It is a library for other scripts to include with the meta directive // @require https://update.greatest.deepsurf.us/scripts/515441/1476487/Nitro%20Type%20Theme%20Customizer.js

  1. // ==UserScript==
  2. // @name Nitro Type Theme Customizer
  3. // @namespace https://greatest.deepsurf.us/users/1331131-tensorflow-dvorak
  4. // @version 1.16
  5. // @author TensorFlow - Dvorak
  6. // @description Theme Customizer
  7. // @match *://www.nitrotype.com/*
  8. // @grant GM_addStyle
  9. // ==/UserScript==
  10.  
  11. (function () {
  12. "use strict";
  13.  
  14. const defaultBgColor = "#060516";
  15. const defaultTextColor = "#a6a4f7";
  16. const defaultCursorColor = "#0075ff";
  17. const defaultButtonColor = "#5a67d8";
  18. const defaultTypedTextColor = "#23223b";
  19. const defaultCardColor = "#1a1a2e";
  20. const defaultTypingAreaColor = "#0605163d";
  21. const defaultFont = '"Arial", sans-serif';
  22.  
  23. const fonts = [
  24. "Arial, sans-serif",
  25. "Verdana, sans-serif",
  26. "Courier New, monospace",
  27. "Georgia, serif",
  28. "Times New Roman, serif",
  29. "Comic Sans MS, cursive",
  30. "Trebuchet MS, sans-serif",
  31. '"Montserrat", sans-serif',
  32. '"Roboto Mono", monospace',
  33. '"Courier New", Courier, monospace',
  34. '"Lucida Sans Typewriter", "Lucida Typewriter", monospace',
  35. ];
  36.  
  37. GM_addStyle(`
  38. #theme-icon {
  39. position: fixed;
  40. bottom: 20px;
  41. left: 20px;
  42. width: 45px;
  43. height: 45px;
  44. background-color: #5a67d8;
  45. border-radius: 50%;
  46. display: flex;
  47. align-items: center;
  48. justify-content: center;
  49. color: #fff;
  50. cursor: pointer;
  51. font-size: 24px;
  52. z-index: 10000;
  53. box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.3);
  54. transition: transform 0.2s ease-in-out;
  55. }
  56.  
  57. #theme-icon:hover {
  58. transform: scale(1.1);
  59. }
  60.  
  61. #theme-modal {
  62. display: none;
  63. position: fixed;
  64. top: 50%;
  65. left: 50%;
  66. transform: translate(-50%, -50%);
  67. width: 360px;
  68. background-color: #1a202c;
  69. border-radius: 12px;
  70. padding: 20px;
  71. box-shadow: 0 12px 24px rgba(0, 0, 0, 0.5);
  72. z-index: 10001;
  73. color: #e2e8f0;
  74. font-family: Arial, sans-serif;
  75. display: grid;
  76. width: fit-content;
  77. grid-template-columns: 1fr 1fr;
  78. gap: 15px;
  79. }
  80.  
  81. #theme-modal h2 {
  82. grid-column: span 2;
  83. margin-top: 0;
  84. color: #e2e8f0;
  85. font-size: 20px;
  86. font-weight: 600;
  87. text-align: center;
  88. padding-bottom: 10px;
  89. border-bottom: 1px solid #2d3748;
  90. }
  91.  
  92. .input-field {
  93. display: flex;
  94. align-items: center;
  95. gap: 10px;
  96. }
  97.  
  98. .input-field label {
  99. font-weight: 500;
  100. color: #a0aec0;
  101. flex: 1;
  102. }
  103.  
  104. .input-field input[type="text"],
  105. .input-field input[type="color"] {
  106. height: 35px;
  107. border: none;
  108. border-radius: 6px;
  109. padding: 0 8px;
  110. background-color: #2d3748;
  111. color: #e2e8f0;
  112. font-size: 14px;
  113. outline: none;
  114. transition: transform 0.2s ease;
  115. }
  116.  
  117. #apply-theme, #reset-theme {
  118. grid-column: span 2;
  119. display: block;
  120. width: 100%;
  121. padding: 12px;
  122. background-color: var(--button-color, #5a67d8);
  123. color: #fff;
  124. border: none;
  125. cursor: pointer;
  126. border-radius: 8px;
  127. font-size: 16px;
  128. font-weight: 600;
  129. text-align: center;
  130. transition: background-color 0.2s ease;
  131. margin-top: 15px;
  132. }
  133.  
  134. #apply-theme:hover, #reset-theme:hover {
  135. background-color: #434190;
  136. }
  137.  
  138. #font-select {
  139. width: 100%;
  140. padding: 8px;
  141. border: 1px solid #4a5568;
  142. border-radius: 6px;
  143. background-color: #2d3748;
  144. color: #e2e8f0;
  145. font-size: 14px;
  146. cursor: pointer;
  147. outline: none;
  148. transition: transform 0.2s ease, background-color 0.2s ease;
  149. }
  150.  
  151. #font-select:hover {
  152. transform: scale(1.02);
  153. background-color: #3b475a;
  154. }
  155. `);
  156.  
  157. const themeIcon = document.createElement("div");
  158. themeIcon.id = "theme-icon";
  159. themeIcon.innerText = "🎨";
  160. document.body.appendChild(themeIcon);
  161.  
  162. const themeModal = document.createElement("div");
  163. themeModal.style.display = "none";
  164. themeModal.id = "theme-modal";
  165. themeModal.innerHTML = `
  166. <h2>Customize Theme</h2>
  167. <div class="input-field">
  168. <label for="bg-color">Background Color</label>
  169. <input type="color" id="bg-color-picker" value="${defaultBgColor}">
  170. <input type="text" id="bg-color" value="${defaultBgColor}">
  171. </div>
  172. <div class="input-field">
  173. <label for="bg-image">Background Image URL</label>
  174. <input type="text" id="bg-image" placeholder="Image URL">
  175. </div>
  176. <div class="input-field">
  177. <label for="text-color">Text Color</label>
  178. <input type="color" id="text-color-picker" value="${defaultTextColor}">
  179. <input type="text" id="text-color" value="${defaultTextColor}">
  180. </div>
  181. <div class="input-field">
  182. <label for="cursor-color">Caret Color</label>
  183. <input type="color" id="cursor-color-picker" value="${defaultCursorColor}">
  184. <input type="text" id="cursor-color" value="${defaultCursorColor}">
  185. </div>
  186. <div class="input-field">
  187. <label for="button-color">Button Color</label>
  188. <input type="color" id="button-color-picker" value="${defaultButtonColor}">
  189. <input type="text" id="button-color" value="${defaultButtonColor}">
  190. </div>
  191. <div class="input-field">
  192. <label for="typed-text-color">Typed Text Color</label>
  193. <input type="color" id="typed-text-color-picker" value="${defaultTypedTextColor}">
  194. <input type="text" id="typed-text-color" value="${defaultTypedTextColor}">
  195. </div>
  196. <div class="input-field">
  197. <label for="card-color">Card Color</label>
  198. <input type="color" id="card-color-picker" value="${defaultCardColor}">
  199. <input type="text" id="card-color" value="${defaultCardColor}">
  200. </div>
  201. <div class="input-field">
  202. <label for="typing-area-color">Typing Area Color</label>
  203. <input type="color" id="typing-area-color-picker" value="${defaultTypingAreaColor}">
  204. <input type="text" id="typing-area-color" value="${defaultTypingAreaColor}">
  205. </div>
  206. <div class="input-field">
  207. <label for="typing-area-image">Typing Area Image URL</label>
  208. <input type="text" id="typing-area-image" placeholder="Image URL">
  209. </div>
  210. <div class="input-field">
  211. <label for="font-select">Font</label>
  212. <select id="font-select">
  213. ${fonts
  214. .map(
  215. (font) =>
  216. `<option value="${font}">${font
  217. .split(",")[0]
  218. .replace(/"/g, "")}</option>`
  219. )
  220. .join("")}
  221. </select>
  222. </div>
  223. <button id="apply-theme">Apply Theme</button>
  224. <button id="reset-theme">Reset to Default</button>
  225. `;
  226.  
  227. document.body.appendChild(themeModal);
  228. themeModal.style.display = "none";
  229.  
  230. function syncColorInputs(pickerId, textId) {
  231. const picker = document.getElementById(pickerId);
  232. const textInput = document.getElementById(textId);
  233.  
  234. picker.addEventListener("input", () => {
  235. textInput.value = picker.value;
  236. });
  237.  
  238. textInput.addEventListener("input", () => {
  239. const colorValue = textInput.value;
  240. if (/^#([A-Fa-f0-9]{8}|[A-Fa-f0-9]{6})$/.test(colorValue)) {
  241. picker.value = colorValue.slice(0, 7);
  242. }
  243. });
  244. }
  245.  
  246. syncColorInputs("bg-color-picker", "bg-color");
  247. syncColorInputs("text-color-picker", "text-color");
  248. syncColorInputs("cursor-color-picker", "cursor-color");
  249. syncColorInputs("button-color-picker", "button-color");
  250. syncColorInputs("typed-text-color-picker", "typed-text-color");
  251. syncColorInputs("card-color-picker", "card-color");
  252. syncColorInputs("typing-area-color-picker", "typing-area-color");
  253.  
  254. function loadTheme() {
  255. document.getElementById("bg-color").value =
  256. localStorage.getItem("nt_bgColor") || defaultBgColor;
  257. document.getElementById("bg-image").value =
  258. localStorage.getItem("nt_bgImage") || "";
  259. document.getElementById("text-color").value =
  260. localStorage.getItem("nt_textColor") || defaultTextColor;
  261. document.getElementById("cursor-color").value =
  262. localStorage.getItem("nt_cursorColor") || defaultCursorColor;
  263. document.getElementById("button-color").value =
  264. localStorage.getItem("nt_buttonColor") || defaultButtonColor;
  265. document.getElementById("typed-text-color").value =
  266. localStorage.getItem("nt_typedTextColor") || defaultTypedTextColor;
  267. document.getElementById("card-color").value =
  268. localStorage.getItem("nt_cardColor") || defaultCardColor;
  269. document.getElementById("typing-area-color").value =
  270. localStorage.getItem("nt_typingAreaColor") || defaultTypingAreaColor;
  271. document.getElementById("typing-area-image").value =
  272. localStorage.getItem("nt_typingAreaImage") || "";
  273. document.getElementById("font-select").value =
  274. localStorage.getItem("nt_font") || defaultFont;
  275. }
  276.  
  277. themeIcon.addEventListener("click", () => {
  278. loadTheme();
  279. themeModal.style.display =
  280. themeModal.style.display === "none" ? "grid" : "none";
  281. });
  282.  
  283. function applyTheme() {
  284. const bgColor = document.getElementById("bg-color").value;
  285. const bgImage = document.getElementById("bg-image").value;
  286. const textColor = document.getElementById("text-color").value;
  287. const cursorColor = document.getElementById("cursor-color").value;
  288. const buttonColor = document.getElementById("button-color").value;
  289. const typedTextColor = document.getElementById("typed-text-color").value;
  290. const cardColor = document.getElementById("card-color").value;
  291. const typingAreaColor = document.getElementById("typing-area-color").value;
  292. const typingAreaImage = document.getElementById("typing-area-image").value;
  293. const font = document.getElementById("font-select").value;
  294.  
  295. document.body.style.backgroundColor = bgColor;
  296. document.body.style.background = bgImage ? `url(${bgImage})` : "";
  297. document.body.style.backgroundSize = "cover";
  298. document.body.style.backgroundAttachment = "fixed";
  299. document.body.style.color = textColor;
  300.  
  301. GM_addStyle(`
  302. .custom-cursor { color: ${cursorColor}; }
  303. .typed-text { color: ${typedTextColor}; }
  304. .card { background-color: ${cardColor}; }
  305. .typing-area {
  306. background-color: ${typingAreaColor};
  307. background: ${
  308. typingAreaImage ? `url(${typingAreaImage})` : "none"
  309. };
  310. background-size: cover;
  311. background-position: center;
  312. }
  313. :root { --button-color: ${buttonColor}; }
  314. `);
  315.  
  316. localStorage.setItem("nt_bgColor", bgColor);
  317. localStorage.setItem("nt_bgImage", bgImage);
  318. localStorage.setItem("nt_textColor", textColor);
  319. localStorage.setItem("nt_cursorColor", cursorColor);
  320. localStorage.setItem("nt_buttonColor", buttonColor);
  321. localStorage.setItem("nt_typedTextColor", typedTextColor);
  322. localStorage.setItem("nt_cardColor", cardColor);
  323. localStorage.setItem("nt_typingAreaColor", typingAreaColor);
  324. localStorage.setItem("nt_typingAreaImage", typingAreaImage);
  325. localStorage.setItem("nt_font", font);
  326.  
  327. themeModal.style.display = "none";
  328. }
  329.  
  330. window.addEventListener("load", () => {
  331. loadTheme();
  332. applyTheme();
  333. });
  334.  
  335. function clearLocalStorageValues() {
  336. const keys = [
  337. "nt_bgColor",
  338. "nt_bgImage",
  339. "nt_textColor",
  340. "nt_cursorColor",
  341. "nt_buttonColor",
  342. "nt_typedTextColor",
  343. "nt_cardColor",
  344. "nt_typingAreaColor",
  345. "nt_typingAreaImage",
  346. "nt_font",
  347. ];
  348.  
  349. keys.forEach((key) => localStorage.removeItem(key));
  350. }
  351.  
  352. function resetTheme() {
  353. clearLocalStorageValues();
  354. document.body.style.backgroundColor = defaultBgColor;
  355. document.body.style.backgroundImage = "";
  356. document.body.style.color = defaultTextColor;
  357. themeModal.style.display = "none";
  358. }
  359.  
  360. document.getElementById("apply-theme").addEventListener("click", applyTheme);
  361. document.getElementById("reset-theme").addEventListener("click", resetTheme);
  362. })();