Kirka Keybind Overlay

Customizable keybind overlay for Kirka.io

  1. // ==UserScript==
  2. // @name Kirka Keybind Overlay
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.0
  5. // @license Life.css - https://github.com/LifeCss
  6. // @description Customizable keybind overlay for Kirka.io
  7. // @author You
  8. // @match https://kirka.io/*
  9. // @match https://snipers.io/*
  10. // @icon https://www.google.com/s2/favicons?sz=64&domain=kirka.io
  11. // @grant none
  12. // ==/UserScript==
  13. (function() {
  14. 'use strict';
  15.  
  16. window.addEventListener('load', () => {
  17. console.log('Script loaded successfully.'); // Debugging
  18.  
  19. // Default settings
  20. const defaultSettings = {
  21. keybindColors: {
  22. W: 'rgba(0, 0, 0, 0.3)',
  23. A: 'rgba(0, 0, 0, 0.3)',
  24. S: 'rgba(0, 0, 0, 0.3)',
  25. D: 'rgba(0, 0, 0, 0.3)',
  26. Shift: 'rgba(0, 0, 0, 0.3)',
  27. LeftMouse: 'rgba(0, 0, 0, 0.3)',
  28. RightMouse: 'rgba(0, 0, 0, 0.3)',
  29. },
  30. keybindButtonSize: '40',
  31. keybindButtonOpacity: '1',
  32. keybindPressedColor: 'rgba(0, 255, 0, 0.7)',
  33. keybindFontSize: '14',
  34. keybindBorderThickness: '2',
  35. keybindDarkMode: 'false',
  36. keybindButtonShape: 'circle',
  37. keybindTheme: 'light',
  38. keybindMenuBackground: 'transparent',
  39. keybindMenuBlur: 'false',
  40. keybindMenuOpaque: 'false',
  41. keybindButtonsVisible: 'true',
  42. keybindButtonOutline: 'true',
  43. keybindButtonPositionX: '20', // Horizontal position
  44. keybindButtonPositionY: '50', // Vertical position
  45. customCSS: '', // Added custom CSS to default settings
  46. sliderColor: '#007BFF', // Default slider color
  47. };
  48.  
  49. // Load saved settings or use defaults
  50. const savedColors = JSON.parse(localStorage.getItem('keybindColors')) || defaultSettings.keybindColors;
  51. const savedButtonSize = localStorage.getItem('keybindButtonSize') || defaultSettings.keybindButtonSize;
  52. const savedButtonOpacity = localStorage.getItem('keybindButtonOpacity') || defaultSettings.keybindButtonOpacity;
  53. const savedPressedColor = localStorage.getItem('keybindPressedColor') || defaultSettings.keybindPressedColor;
  54. const savedFontSize = localStorage.getItem('keybindFontSize') || defaultSettings.keybindFontSize;
  55. const savedBorderThickness = localStorage.getItem('keybindBorderThickness') || defaultSettings.keybindBorderThickness;
  56. const savedDarkMode = localStorage.getItem('keybindDarkMode') || defaultSettings.keybindDarkMode;
  57. const savedButtonShape = localStorage.getItem('keybindButtonShape') || defaultSettings.keybindButtonShape;
  58. const savedTheme = localStorage.getItem('keybindTheme') || defaultSettings.keybindTheme;
  59. const savedMenuBackground = localStorage.getItem('keybindMenuBackground') || defaultSettings.keybindMenuBackground;
  60. const savedMenuBlur = localStorage.getItem('keybindMenuBlur') || defaultSettings.keybindMenuBlur;
  61. const savedMenuOpaque = localStorage.getItem('keybindMenuOpaque') || defaultSettings.keybindMenuOpaque;
  62. const savedButtonsVisible = localStorage.getItem('keybindButtonsVisible') || defaultSettings.keybindButtonsVisible;
  63. const savedButtonOutline = localStorage.getItem('keybindButtonOutline') || defaultSettings.keybindButtonOutline;
  64. const savedButtonPositionX = localStorage.getItem('keybindButtonPositionX') || defaultSettings.keybindButtonPositionX;
  65. const savedButtonPositionY = localStorage.getItem('keybindButtonPositionY') || defaultSettings.keybindButtonPositionY;
  66. const savedCustomCSS = localStorage.getItem('customCSS') || defaultSettings.customCSS; // Load saved CSS
  67. const savedSliderColor = localStorage.getItem('sliderColor') || defaultSettings.sliderColor; // Load saved slider color
  68.  
  69. const keys = [
  70. { id: 'W', label: 'W', keyCode: 'KeyW' },
  71. { id: 'A', label: 'A', keyCode: 'KeyA' },
  72. { id: 'S', label: 'S', keyCode: 'KeyS' },
  73. { id: 'D', label: 'D', keyCode: 'KeyD' },
  74. { id: 'Shift', label: 'Shift', keyCode: 'ShiftLeft' },
  75. { id: 'LeftMouse', label: 'LMB', keyCode: 'Mouse0' },
  76. { id: 'RightMouse', label: 'RMB', keyCode: 'Mouse2' },
  77. ];
  78.  
  79. let pressedColor = savedPressedColor;
  80. let fontSize = parseInt(savedFontSize, 10);
  81. let borderThickness = parseInt(savedBorderThickness, 10);
  82. let buttonSize = parseInt(savedButtonSize, 10);
  83. let buttonOpacity = parseFloat(savedButtonOpacity);
  84. let buttonShape = savedButtonShape;
  85. let isDarkMode = savedDarkMode === 'true';
  86. let currentTheme = savedTheme;
  87. let menuBackground = savedMenuBackground;
  88. let menuBlur = savedMenuBlur === 'true';
  89. let menuOpaque = savedMenuOpaque === 'true';
  90. let buttonsVisible = savedButtonsVisible === 'true';
  91. let buttonOutline = savedButtonOutline === 'true';
  92. let buttonPositionX = parseInt(savedButtonPositionX, 10); // Horizontal position
  93. let buttonPositionY = parseInt(savedButtonPositionY, 10); // Vertical position
  94. let customCSS = savedCustomCSS; // Load saved CSS
  95. let sliderColor = savedSliderColor; // Load saved slider color
  96.  
  97. let buttonColors = { ...savedColors };
  98.  
  99. const container = document.createElement('div');
  100. container.style.position = 'fixed';
  101. container.style.left = `${buttonPositionX}px`; // Set initial horizontal position
  102. container.style.top = `${buttonPositionY}%`; // Set initial vertical position
  103. container.style.transform = 'translateY(-50%)';
  104. container.style.display = buttonsVisible ? 'flex' : 'none';
  105. container.style.flexDirection = 'column';
  106. container.style.alignItems = 'center';
  107. container.style.zIndex = '9999';
  108. container.style.opacity = buttonOpacity;
  109.  
  110. const buttonElements = {};
  111.  
  112. function createButton(key) {
  113. const button = document.createElement('div');
  114. button.id = key.id;
  115. button.style.width = `${buttonSize}px`;
  116. button.style.height = `${buttonSize}px`;
  117. button.style.borderRadius = buttonShape === 'circle' ? '50%' : '0';
  118. button.style.margin = '5px';
  119. button.style.backgroundColor = buttonColors[key.id];
  120. button.style.border = buttonOutline ? `${borderThickness}px solid ${isDarkMode ? 'black' : 'white'}` : 'none';
  121. button.style.display = 'flex';
  122. button.style.justifyContent = 'center';
  123. button.style.alignItems = 'center';
  124. button.style.color = 'white';
  125. button.style.fontSize = `${fontSize}px`;
  126. button.style.fontWeight = 'bold';
  127. button.innerText = key.label;
  128. button.style.transition = 'background-color 0.2s ease';
  129. buttonElements[key.id] = button;
  130. return button;
  131. }
  132.  
  133. keys.forEach(key => {
  134. const button = createButton(key);
  135. container.appendChild(button);
  136. });
  137. document.body.appendChild(container);
  138.  
  139. // Event listeners for key and mouse presses
  140. document.addEventListener('keydown', (event) => {
  141. const key = keys.find(k => k.keyCode === event.code);
  142. if (key) {
  143. const button = buttonElements[key.id];
  144. button.style.backgroundColor = pressedColor;
  145. }
  146. });
  147.  
  148. document.addEventListener('keyup', (event) => {
  149. const key = keys.find(k => k.keyCode === event.code);
  150. if (key) {
  151. const button = buttonElements[key.id];
  152. button.style.backgroundColor = buttonColors[key.id];
  153. }
  154. });
  155.  
  156. document.addEventListener('mousedown', (event) => {
  157. if (event.button === 0) { // Left mouse button
  158. const button = buttonElements['LeftMouse'];
  159. button.style.backgroundColor = pressedColor;
  160. } else if (event.button === 2) { // Right mouse button
  161. const button = buttonElements['RightMouse'];
  162. button.style.backgroundColor = pressedColor;
  163. }
  164. });
  165.  
  166. document.addEventListener('mouseup', (event) => {
  167. if (event.button === 0) { // Left mouse button
  168. const button = buttonElements['LeftMouse'];
  169. button.style.backgroundColor = buttonColors['LeftMouse'];
  170. } else if (event.button === 2) { // Right mouse button
  171. const button = buttonElements['RightMouse'];
  172. button.style.backgroundColor = buttonColors['RightMouse'];
  173. }
  174. });
  175.  
  176. // Settings menu creation
  177. let colorMenuVisible = false;
  178. const menu = document.createElement('div');
  179. menu.style.position = 'fixed';
  180. menu.style.top = '50%';
  181. menu.style.left = '50%';
  182. menu.style.transform = 'translate(-50%, -50%)';
  183. menu.style.display = 'grid';
  184. menu.style.gridTemplateColumns = 'repeat(3, 1fr)';
  185. menu.style.gap = '10px';
  186. menu.style.backgroundColor = menuOpaque ? (isDarkMode ? 'rgba(0, 0, 0, 0.8)' : 'rgba(255, 255, 255, 0.8)') : menuBackground;
  187. menu.style.color = isDarkMode ? 'white' : 'black';
  188. menu.style.padding = '20px';
  189. menu.style.width = '600px';
  190. menu.style.borderRadius = '10px';
  191. menu.style.boxShadow = '0 0 15px rgba(0, 0, 0, 0.2)';
  192. menu.style.zIndex = '10000';
  193. menu.style.display = 'none';
  194. menu.style.opacity = '0';
  195. menu.style.transition = 'opacity 0.3s ease, transform 0.3s ease';
  196. menu.style.backdropFilter = menuBlur ? 'blur(10px)' : 'none';
  197.  
  198. // Color inputs
  199. keys.forEach(key => {
  200. const colorInputContainer = document.createElement('div');
  201. colorInputContainer.style.display = 'flex';
  202. colorInputContainer.style.flexDirection = 'column';
  203. colorInputContainer.style.alignItems = 'center';
  204.  
  205. const label = document.createElement('label');
  206. label.innerText = `${key.label} Color: `;
  207. label.style.marginBottom = '5px';
  208.  
  209. const colorInput = document.createElement('input');
  210. colorInput.type = 'color';
  211. colorInput.value = buttonColors[key.id];
  212. colorInput.style.marginBottom = '10px';
  213.  
  214. colorInput.addEventListener('input', function() {
  215. buttonColors[key.id] = colorInput.value;
  216. const button = document.getElementById(key.id);
  217. button.style.backgroundColor = colorInput.value;
  218. localStorage.setItem('keybindColors', JSON.stringify(buttonColors));
  219. });
  220.  
  221. colorInputContainer.appendChild(label);
  222. colorInputContainer.appendChild(colorInput);
  223. menu.appendChild(colorInputContainer);
  224. });
  225.  
  226. // Pressed color picker
  227. const pressedColorContainer = document.createElement('div');
  228. pressedColorContainer.style.display = 'flex';
  229. pressedColorContainer.style.flexDirection = 'column';
  230. pressedColorContainer.style.alignItems = 'center';
  231.  
  232. const pressedColorLabel = document.createElement('label');
  233. pressedColorLabel.innerText = 'Pressed Color: ';
  234. pressedColorLabel.style.marginBottom = '5px';
  235.  
  236. const pressedColorInput = document.createElement('input');
  237. pressedColorInput.type = 'color';
  238. pressedColorInput.value = pressedColor;
  239. pressedColorInput.style.marginBottom = '10px';
  240.  
  241. pressedColorInput.addEventListener('input', function() {
  242. pressedColor = pressedColorInput.value;
  243. localStorage.setItem('keybindPressedColor', pressedColor);
  244. });
  245.  
  246. pressedColorContainer.appendChild(pressedColorLabel);
  247. pressedColorContainer.appendChild(pressedColorInput);
  248. menu.appendChild(pressedColorContainer);
  249.  
  250. // Button size slider
  251. const sizeContainer = document.createElement('div');
  252. sizeContainer.style.display = 'flex';
  253. sizeContainer.style.flexDirection = 'column';
  254. sizeContainer.style.alignItems = 'center';
  255.  
  256. const sizeLabel = document.createElement('label');
  257. sizeLabel.innerText = 'Button Size: ';
  258. sizeLabel.style.marginBottom = '5px';
  259.  
  260. const sizeSlider = document.createElement('input');
  261. sizeSlider.type = 'range';
  262. sizeSlider.min = '20';
  263. sizeSlider.max = '100';
  264. sizeSlider.value = buttonSize;
  265. sizeSlider.addEventListener('input', function() {
  266. buttonSize = parseInt(sizeSlider.value, 10);
  267. updateButtonSize(buttonSize);
  268. });
  269.  
  270. sizeContainer.appendChild(sizeLabel);
  271. sizeContainer.appendChild(sizeSlider);
  272. menu.appendChild(sizeContainer);
  273.  
  274. // Button opacity slider
  275. const opacityContainer = document.createElement('div');
  276. opacityContainer.style.display = 'flex';
  277. opacityContainer.style.flexDirection = 'column';
  278. opacityContainer.style.alignItems = 'center';
  279.  
  280. const opacityLabel = document.createElement('label');
  281. opacityLabel.innerText = 'Button Opacity: ';
  282. opacityLabel.style.marginBottom = '5px';
  283.  
  284. const opacitySlider = document.createElement('input');
  285. opacitySlider.type = 'range';
  286. opacitySlider.min = '0.1';
  287. opacitySlider.max = '1';
  288. opacitySlider.step = '0.1';
  289. opacitySlider.value = buttonOpacity;
  290. opacitySlider.addEventListener('input', function() {
  291. buttonOpacity = parseFloat(opacitySlider.value);
  292. updateButtonOpacity(buttonOpacity);
  293. });
  294.  
  295. opacityContainer.appendChild(opacityLabel);
  296. opacityContainer.appendChild(opacitySlider);
  297. menu.appendChild(opacityContainer);
  298.  
  299. // Button shape toggle
  300. const shapeContainer = document.createElement('div');
  301. shapeContainer.style.display = 'flex';
  302. shapeContainer.style.flexDirection = 'column';
  303. shapeContainer.style.alignItems = 'center';
  304.  
  305. const shapeLabel = document.createElement('label');
  306. shapeLabel.innerText = 'Button Shape: ';
  307. shapeLabel.style.marginBottom = '5px';
  308.  
  309. const shapeToggle = document.createElement('button');
  310. shapeToggle.innerText = buttonShape === 'circle' ? 'Switch to Square' : 'Switch to Circle';
  311. shapeToggle.addEventListener('click', () => {
  312. buttonShape = buttonShape === 'circle' ? 'square' : 'circle';
  313. shapeToggle.innerText = buttonShape === 'circle' ? 'Switch to Square' : 'Switch to Circle';
  314. updateButtonShape(buttonShape);
  315. });
  316.  
  317. shapeContainer.appendChild(shapeLabel);
  318. shapeContainer.appendChild(shapeToggle);
  319. menu.appendChild(shapeContainer);
  320.  
  321. // Theme dropdown
  322. const themeContainer = document.createElement('div');
  323. themeContainer.style.display = 'flex';
  324. themeContainer.style.flexDirection = 'column';
  325. themeContainer.style.alignItems = 'center';
  326.  
  327. const themeLabel = document.createElement('label');
  328. themeLabel.innerText = 'Theme: ';
  329. themeLabel.style.marginBottom = '5px';
  330.  
  331. const themeDropdown = document.createElement('select');
  332. themeDropdown.innerHTML = `
  333. <option value="light">Light</option>
  334. <option value="dark">Dark</option>
  335. <option value="custom">Custom</option>
  336. `;
  337. themeDropdown.value = currentTheme;
  338. themeDropdown.addEventListener('change', () => {
  339. currentTheme = themeDropdown.value;
  340. applyTheme(currentTheme);
  341. });
  342.  
  343. themeContainer.appendChild(themeLabel);
  344. themeContainer.appendChild(themeDropdown);
  345. menu.appendChild(themeContainer);
  346.  
  347. // Menu background style dropdown
  348. const menuBackgroundContainer = document.createElement('div');
  349. menuBackgroundContainer.style.display = 'flex';
  350. menuBackgroundContainer.style.flexDirection = 'column';
  351. menuBackgroundContainer.style.alignItems = 'center';
  352.  
  353. const menuBackgroundLabel = document.createElement('label');
  354. menuBackgroundLabel.innerText = 'Menu Background: ';
  355. menuBackgroundLabel.style.marginBottom = '5px';
  356.  
  357. const menuBackgroundDropdown = document.createElement('select');
  358. menuBackgroundDropdown.innerHTML = `
  359. <option value="transparent">Transparent</option>
  360. <option value="opaque">Opaque</option>
  361. `;
  362. menuBackgroundDropdown.value = menuBackground;
  363. menuBackgroundDropdown.addEventListener('change', () => {
  364. menuBackground = menuBackgroundDropdown.value;
  365. updateMenuBackground(menuBackground);
  366. });
  367.  
  368. menuBackgroundContainer.appendChild(menuBackgroundLabel);
  369. menuBackgroundContainer.appendChild(menuBackgroundDropdown);
  370. menu.appendChild(menuBackgroundContainer);
  371.  
  372. // Menu blur toggle
  373. const menuBlurContainer = document.createElement('div');
  374. menuBlurContainer.style.display = 'flex';
  375. menuBlurContainer.style.flexDirection = 'column';
  376. menuBlurContainer.style.alignItems = 'center';
  377.  
  378. const menuBlurLabel = document.createElement('label');
  379. menuBlurLabel.innerText = 'Menu Blur: ';
  380. menuBlurLabel.style.marginBottom = '5px';
  381.  
  382. const menuBlurToggle = document.createElement('button');
  383. menuBlurToggle.innerText = menuBlur ? 'Disable Blur' : 'Enable Blur';
  384. menuBlurToggle.addEventListener('click', () => {
  385. menuBlur = !menuBlur;
  386. menuBlurToggle.innerText = menuBlur ? 'Disable Blur' : 'Enable Blur';
  387. updateMenuBlur(menuBlur);
  388. });
  389.  
  390. menuBlurContainer.appendChild(menuBlurLabel);
  391. menuBlurContainer.appendChild(menuBlurToggle);
  392. menu.appendChild(menuBlurContainer);
  393.  
  394. // Menu opaque toggle
  395. const menuOpaqueContainer = document.createElement('div');
  396. menuOpaqueContainer.style.display = 'flex';
  397. menuOpaqueContainer.style.flexDirection = 'column';
  398. menuOpaqueContainer.style.alignItems = 'center';
  399.  
  400. const menuOpaqueLabel = document.createElement('label');
  401. menuOpaqueLabel.innerText = 'Menu Opaque: ';
  402. menuOpaqueLabel.style.marginBottom = '5px';
  403.  
  404. const menuOpaqueToggle = document.createElement('button');
  405. menuOpaqueToggle.innerText = menuOpaque ? 'Disable Opaque' : 'Enable Opaque';
  406. menuOpaqueToggle.addEventListener('click', () => {
  407. menuOpaque = !menuOpaque;
  408. menuOpaqueToggle.innerText = menuOpaque ? 'Disable Opaque' : 'Enable Opaque';
  409. updateMenuOpaque(menuOpaque);
  410. });
  411.  
  412. menuOpaqueContainer.appendChild(menuOpaqueLabel);
  413. menuOpaqueContainer.appendChild(menuOpaqueToggle);
  414. menu.appendChild(menuOpaqueContainer);
  415.  
  416. // Button visibility toggle
  417. const buttonsVisibleContainer = document.createElement('div');
  418. buttonsVisibleContainer.style.display = 'flex';
  419. buttonsVisibleContainer.style.flexDirection = 'column';
  420. buttonsVisibleContainer.style.alignItems = 'center';
  421.  
  422. const buttonsVisibleLabel = document.createElement('label');
  423. buttonsVisibleLabel.innerText = 'Show Buttons: ';
  424. buttonsVisibleLabel.style.marginBottom = '5px';
  425.  
  426. const buttonsVisibleToggle = document.createElement('button');
  427. buttonsVisibleToggle.innerText = buttonsVisible ? 'Hide Buttons' : 'Show Buttons';
  428. buttonsVisibleToggle.addEventListener('click', () => {
  429. buttonsVisible = !buttonsVisible;
  430. buttonsVisibleToggle.innerText = buttonsVisible ? 'Hide Buttons' : 'Show Buttons';
  431. updateButtonsVisibility(buttonsVisible);
  432. });
  433.  
  434. buttonsVisibleContainer.appendChild(buttonsVisibleLabel);
  435. buttonsVisibleContainer.appendChild(buttonsVisibleToggle);
  436. menu.appendChild(buttonsVisibleContainer);
  437.  
  438. // Button outline toggle
  439. const buttonOutlineContainer = document.createElement('div');
  440. buttonOutlineContainer.style.display = 'flex';
  441. buttonOutlineContainer.style.flexDirection = 'column';
  442. buttonOutlineContainer.style.alignItems = 'center';
  443.  
  444. const buttonOutlineLabel = document.createElement('label');
  445. buttonOutlineLabel.innerText = 'Button Outline: ';
  446. buttonOutlineLabel.style.marginBottom = '5px';
  447.  
  448. const buttonOutlineToggle = document.createElement('button');
  449. buttonOutlineToggle.innerText = buttonOutline ? 'Disable Outline' : 'Enable Outline';
  450. buttonOutlineToggle.addEventListener('click', () => {
  451. buttonOutline = !buttonOutline;
  452. buttonOutlineToggle.innerText = buttonOutline ? 'Disable Outline' : 'Enable Outline';
  453. updateButtonOutline(buttonOutline);
  454. });
  455.  
  456. buttonOutlineContainer.appendChild(buttonOutlineLabel);
  457. buttonOutlineContainer.appendChild(buttonOutlineToggle);
  458. menu.appendChild(buttonOutlineContainer);
  459.  
  460. // Button position sliders
  461. const positionXContainer = document.createElement('div');
  462. positionXContainer.style.display = 'flex';
  463. positionXContainer.style.flexDirection = 'column';
  464. positionXContainer.style.alignItems = 'center';
  465.  
  466. const positionXLabel = document.createElement('label');
  467. positionXLabel.innerText = 'Horizontal Position: ';
  468. positionXLabel.style.marginBottom = '5px';
  469.  
  470. const positionXSlider = document.createElement('input');
  471. positionXSlider.type = 'range';
  472. positionXSlider.min = '-50'; // Extended range for horizontal position
  473. positionXSlider.max = '150'; // Extended range for horizontal position
  474. positionXSlider.value = buttonPositionX;
  475. positionXSlider.addEventListener('input', function() {
  476. buttonPositionX = parseInt(positionXSlider.value, 10);
  477. updateButtonPosition();
  478. });
  479.  
  480. positionXContainer.appendChild(positionXLabel);
  481. positionXContainer.appendChild(positionXSlider);
  482. menu.appendChild(positionXContainer);
  483.  
  484. const positionYContainer = document.createElement('div');
  485. positionYContainer.style.display = 'flex';
  486. positionYContainer.style.flexDirection = 'column';
  487. positionYContainer.style.alignItems = 'center';
  488.  
  489. const positionYLabel = document.createElement('label');
  490. positionYLabel.innerText = 'Vertical Position: ';
  491. positionYLabel.style.marginBottom = '5px';
  492.  
  493. const positionYSlider = document.createElement('input');
  494. positionYSlider.type = 'range';
  495. positionYSlider.min = '0';
  496. positionYSlider.max = '100';
  497. positionYSlider.value = buttonPositionY;
  498. positionYSlider.addEventListener('input', function() {
  499. buttonPositionY = parseInt(positionYSlider.value, 10);
  500. updateButtonPosition();
  501. });
  502.  
  503. positionYContainer.appendChild(positionYLabel);
  504. positionYContainer.appendChild(positionYSlider);
  505. menu.appendChild(positionYContainer);
  506.  
  507. // Reset to defaults button
  508. const resetContainer = document.createElement('div');
  509. resetContainer.style.display = 'flex';
  510. resetContainer.style.flexDirection = 'column';
  511. resetContainer.style.alignItems = 'center';
  512.  
  513. const resetButton = document.createElement('button');
  514. resetButton.innerText = 'Reset to Defaults';
  515. resetButton.addEventListener('click', () => {
  516. resetToDefaults();
  517. });
  518.  
  519. resetContainer.appendChild(resetButton);
  520. menu.appendChild(resetContainer);
  521.  
  522. // Add Live CSS Injector to the menu
  523. const cssInjectorContainer = document.createElement('div');
  524. cssInjectorContainer.style.display = 'flex';
  525. cssInjectorContainer.style.flexDirection = 'column';
  526. cssInjectorContainer.style.alignItems = 'center';
  527.  
  528. const cssInjectorLabel = document.createElement('label');
  529. cssInjectorLabel.innerText = 'Live CSS Injector:';
  530. cssInjectorLabel.style.marginBottom = '5px';
  531.  
  532. const cssTextarea = document.createElement('textarea');
  533. cssTextarea.style.width = '100%';
  534. cssTextarea.style.height = '100px';
  535. cssTextarea.style.marginBottom = '10px';
  536. cssTextarea.style.backgroundColor = isDarkMode ? 'rgba(0, 0, 0, 0.5)' : 'rgba(255, 255, 255, 0.5)';
  537. cssTextarea.style.color = isDarkMode ? 'white' : 'black';
  538. cssTextarea.style.border = 'none';
  539. cssTextarea.style.borderRadius = '5px';
  540. cssTextarea.style.padding = '10px';
  541. cssTextarea.value = customCSS; // Load saved CSS
  542.  
  543. const applyCssButton = document.createElement('button');
  544. applyCssButton.innerText = 'Apply CSS';
  545. applyCssButton.style.backgroundColor = isDarkMode ? '#444' : '#ddd';
  546. applyCssButton.style.color = isDarkMode ? 'white' : 'black';
  547. applyCssButton.style.border = 'none';
  548. applyCssButton.style.borderRadius = '5px';
  549. applyCssButton.style.padding = '10px';
  550. applyCssButton.style.cursor = 'pointer';
  551.  
  552. applyCssButton.addEventListener('click', () => {
  553. customCSS = cssTextarea.value;
  554. localStorage.setItem('customCSS', customCSS); // Save CSS to localStorage
  555. applyCustomCSS(customCSS); // Apply the CSS
  556. });
  557.  
  558. cssInjectorContainer.appendChild(cssInjectorLabel);
  559. cssInjectorContainer.appendChild(cssTextarea);
  560. cssInjectorContainer.appendChild(applyCssButton);
  561. menu.appendChild(cssInjectorContainer);
  562.  
  563. // Add Slider Color Picker to the menu
  564. const sliderColorContainer = document.createElement('div');
  565. sliderColorContainer.style.display = 'flex';
  566. sliderColorContainer.style.flexDirection = 'column';
  567. sliderColorContainer.style.alignItems = 'center';
  568.  
  569. const sliderColorLabel = document.createElement('label');
  570. sliderColorLabel.innerText = 'Slider Color: ';
  571. sliderColorLabel.style.marginBottom = '5px';
  572.  
  573. const sliderColorInput = document.createElement('input');
  574. sliderColorInput.type = 'color';
  575. sliderColorInput.value = sliderColor;
  576. sliderColorInput.style.marginBottom = '10px';
  577.  
  578. sliderColorInput.addEventListener('input', function() {
  579. sliderColor = sliderColorInput.value;
  580. localStorage.setItem('sliderColor', sliderColor); // Save slider color to localStorage
  581. updateSliderColor(sliderColor); // Apply the new slider color
  582. });
  583.  
  584. sliderColorContainer.appendChild(sliderColorLabel);
  585. sliderColorContainer.appendChild(sliderColorInput);
  586. menu.appendChild(sliderColorContainer);
  587.  
  588. document.body.appendChild(menu);
  589.  
  590. // Apply saved CSS on page load
  591. if (customCSS) {
  592. applyCustomCSS(customCSS);
  593. }
  594.  
  595. // Apply saved slider color on page load
  596. updateSliderColor(sliderColor);
  597.  
  598. // Helper functions
  599. function applyCustomCSS(css) {
  600. const styleElement = document.createElement('style');
  601. styleElement.type = 'text/css';
  602. styleElement.innerHTML = css;
  603. document.head.appendChild(styleElement);
  604. }
  605.  
  606. function updateSliderColor(color) {
  607. const sliders = document.querySelectorAll('input[type="range"]');
  608. sliders.forEach(slider => {
  609. slider.style.accentColor = color; // Modern browsers support accent-color
  610. });
  611. }
  612.  
  613. function updateButtonSize(newSize) {
  614. Object.values(buttonElements).forEach(button => {
  615. button.style.width = `${newSize}px`;
  616. button.style.height = `${newSize}px`;
  617. });
  618. localStorage.setItem('keybindButtonSize', newSize.toString());
  619. }
  620.  
  621. function updateButtonOpacity(newOpacity) {
  622. container.style.opacity = newOpacity;
  623. localStorage.setItem('keybindButtonOpacity', newOpacity.toString());
  624. }
  625.  
  626. function updateButtonShape(newShape) {
  627. Object.values(buttonElements).forEach(button => {
  628. button.style.borderRadius = newShape === 'circle' ? '50%' : '0';
  629. });
  630. localStorage.setItem('keybindButtonShape', newShape);
  631. }
  632.  
  633. function applyTheme(theme) {
  634. isDarkMode = theme === 'dark';
  635. menu.style.backgroundColor = menuOpaque ? (isDarkMode ? 'rgba(0, 0, 0, 0.8)' : 'rgba(255, 255, 255, 0.8)') : menuBackground;
  636. menu.style.color = isDarkMode ? 'white' : 'black';
  637. Object.values(buttonElements).forEach(button => {
  638. button.style.border = buttonOutline ? `${borderThickness}px solid ${isDarkMode ? 'black' : 'white'}` : 'none';
  639. });
  640. localStorage.setItem('keybindTheme', theme);
  641. }
  642.  
  643. function updateMenuBackground(background) {
  644. menuBackground = background;
  645. menu.style.backgroundColor = menuOpaque ? (isDarkMode ? 'rgba(0, 0, 0, 0.8)' : 'rgba(255, 255, 255, 0.8)') : background;
  646. localStorage.setItem('keybindMenuBackground', background);
  647. }
  648.  
  649. function updateMenuBlur(blur) {
  650. menuBlur = blur;
  651. menu.style.backdropFilter = blur ? 'blur(10px)' : 'none';
  652. localStorage.setItem('keybindMenuBlur', blur.toString());
  653. }
  654.  
  655. function updateMenuOpaque(opaque) {
  656. menuOpaque = opaque;
  657. menu.style.backgroundColor = opaque ? (isDarkMode ? 'rgba(0, 0, 0, 0.8)' : 'rgba(255, 255, 255, 0.8)') : menuBackground;
  658. localStorage.setItem('keybindMenuOpaque', opaque.toString());
  659. }
  660.  
  661. function updateButtonsVisibility(visible) {
  662. container.style.display = visible ? 'flex' : 'none';
  663. localStorage.setItem('keybindButtonsVisible', visible.toString());
  664. }
  665.  
  666. function updateButtonOutline(outline) {
  667. buttonOutline = outline;
  668. Object.values(buttonElements).forEach(button => {
  669. button.style.border = outline ? `${borderThickness}px solid ${isDarkMode ? 'black' : 'white'}` : 'none';
  670. });
  671. localStorage.setItem('keybindButtonOutline', outline.toString());
  672. }
  673.  
  674. function updateButtonPosition() {
  675. container.style.left = `${buttonPositionX}px`;
  676. container.style.top = `${buttonPositionY}%`;
  677. localStorage.setItem('keybindButtonPositionX', buttonPositionX.toString());
  678. localStorage.setItem('keybindButtonPositionY', buttonPositionY.toString());
  679. }
  680.  
  681. function resetToDefaults() {
  682. buttonColors = { ...defaultSettings.keybindColors };
  683. buttonSize = parseInt(defaultSettings.keybindButtonSize, 10);
  684. buttonOpacity = parseFloat(defaultSettings.keybindButtonOpacity);
  685. pressedColor = defaultSettings.keybindPressedColor;
  686. fontSize = parseInt(defaultSettings.keybindFontSize, 10);
  687. borderThickness = parseInt(defaultSettings.keybindBorderThickness, 10);
  688. buttonShape = defaultSettings.keybindButtonShape;
  689. currentTheme = defaultSettings.keybindTheme;
  690. menuBackground = defaultSettings.keybindMenuBackground;
  691. menuBlur = defaultSettings.keybindMenuBlur === 'true';
  692. menuOpaque = defaultSettings.keybindMenuOpaque === 'true';
  693. buttonsVisible = defaultSettings.keybindButtonsVisible === 'true';
  694. buttonOutline = defaultSettings.keybindButtonOutline === 'true';
  695. buttonPositionX = parseInt(defaultSettings.keybindButtonPositionX, 10);
  696. buttonPositionY = parseInt(defaultSettings.keybindButtonPositionY, 10);
  697. customCSS = defaultSettings.customCSS; // Reset CSS to default
  698. sliderColor = defaultSettings.sliderColor; // Reset slider color to default
  699.  
  700. // Update UI
  701. keys.forEach(key => {
  702. const button = document.getElementById(key.id);
  703. button.style.backgroundColor = buttonColors[key.id];
  704. });
  705. updateButtonSize(buttonSize);
  706. updateButtonOpacity(buttonOpacity);
  707. updateButtonShape(buttonShape);
  708. applyTheme(currentTheme);
  709. updateMenuBackground(menuBackground);
  710. updateMenuBlur(menuBlur);
  711. updateMenuOpaque(menuOpaque);
  712. updateButtonsVisibility(buttonsVisible);
  713. updateButtonOutline(buttonOutline);
  714. updateButtonPosition();
  715. updateSliderColor(sliderColor); // Reset slider color
  716.  
  717. // Update settings menu
  718. pressedColorInput.value = pressedColor;
  719. sizeSlider.value = buttonSize;
  720. opacitySlider.value = buttonOpacity;
  721. shapeToggle.innerText = buttonShape === 'circle' ? 'Switch to Square' : 'Switch to Circle';
  722. themeDropdown.value = currentTheme;
  723. menuBackgroundDropdown.value = menuBackground;
  724. menuBlurToggle.innerText = menuBlur ? 'Disable Blur' : 'Enable Blur';
  725. menuOpaqueToggle.innerText = menuOpaque ? 'Disable Opaque' : 'Enable Opaque';
  726. buttonsVisibleToggle.innerText = buttonsVisible ? 'Hide Buttons' : 'Show Buttons';
  727. buttonOutlineToggle.innerText = buttonOutline ? 'Disable Outline' : 'Enable Outline';
  728. positionXSlider.value = buttonPositionX;
  729. positionYSlider.value = buttonPositionY;
  730. cssTextarea.value = customCSS; // Reset CSS textarea
  731. sliderColorInput.value = sliderColor; // Reset slider color input
  732.  
  733. // Save defaults to localStorage
  734. localStorage.setItem('keybindColors', JSON.stringify(buttonColors));
  735. localStorage.setItem('keybindButtonSize', buttonSize.toString());
  736. localStorage.setItem('keybindButtonOpacity', buttonOpacity.toString());
  737. localStorage.setItem('keybindPressedColor', pressedColor);
  738. localStorage.setItem('keybindFontSize', fontSize.toString());
  739. localStorage.setItem('keybindBorderThickness', borderThickness.toString());
  740. localStorage.setItem('keybindButtonShape', buttonShape);
  741. localStorage.setItem('keybindTheme', currentTheme);
  742. localStorage.setItem('keybindMenuBackground', menuBackground);
  743. localStorage.setItem('keybindMenuBlur', menuBlur.toString());
  744. localStorage.setItem('keybindMenuOpaque', menuOpaque.toString());
  745. localStorage.setItem('keybindButtonsVisible', buttonsVisible.toString());
  746. localStorage.setItem('keybindButtonOutline', buttonOutline.toString());
  747. localStorage.setItem('keybindButtonPositionX', buttonPositionX.toString());
  748. localStorage.setItem('keybindButtonPositionY', buttonPositionY.toString());
  749. localStorage.setItem('customCSS', customCSS); // Save default CSS
  750. localStorage.setItem('sliderColor', sliderColor); // Save default slider color
  751. }
  752.  
  753. // Add Export Settings Button
  754. const exportContainer = document.createElement('div');
  755. exportContainer.style.display = 'flex';
  756. exportContainer.style.flexDirection = 'column';
  757. exportContainer.style.alignItems = 'center';
  758.  
  759. const exportButton = document.createElement('button');
  760. exportButton.innerText = 'Export Settings';
  761. exportButton.addEventListener('click', exportSettings);
  762.  
  763. exportContainer.appendChild(exportButton);
  764. menu.appendChild(exportContainer);
  765.  
  766. // Add Import Settings Button
  767. const importContainer = document.createElement('div');
  768. importContainer.style.display = 'flex';
  769. importContainer.style.flexDirection = 'column';
  770. importContainer.style.alignItems = 'center';
  771.  
  772. const importButton = document.createElement('button');
  773. importButton.innerText = 'Import Settings';
  774. const fileInput = document.createElement('input');
  775. fileInput.type = 'file';
  776. fileInput.accept = '.json';
  777. fileInput.style.display = 'none';
  778. fileInput.addEventListener('change', importSettings);
  779. importButton.addEventListener('click', () => fileInput.click());
  780.  
  781. importContainer.appendChild(importButton);
  782. importContainer.appendChild(fileInput);
  783. menu.appendChild(importContainer);
  784.  
  785. // Export Settings Function
  786. function exportSettings() {
  787. const settings = {
  788. keybindColors: JSON.parse(localStorage.getItem('keybindColors')) || defaultSettings.keybindColors,
  789. keybindButtonSize: localStorage.getItem('keybindButtonSize') || defaultSettings.keybindButtonSize,
  790. keybindButtonOpacity: localStorage.getItem('keybindButtonOpacity') || defaultSettings.keybindButtonOpacity,
  791. keybindPressedColor: localStorage.getItem('keybindPressedColor') || defaultSettings.keybindPressedColor,
  792. keybindFontSize: localStorage.getItem('keybindFontSize') || defaultSettings.keybindFontSize,
  793. keybindBorderThickness: localStorage.getItem('keybindBorderThickness') || defaultSettings.keybindBorderThickness,
  794. keybindDarkMode: localStorage.getItem('keybindDarkMode') || defaultSettings.keybindDarkMode,
  795. keybindButtonShape: localStorage.getItem('keybindButtonShape') || defaultSettings.keybindButtonShape,
  796. keybindTheme: localStorage.getItem('keybindTheme') || defaultSettings.keybindTheme,
  797. keybindMenuBackground: localStorage.getItem('keybindMenuBackground') || defaultSettings.keybindMenuBackground,
  798. keybindMenuBlur: localStorage.getItem('keybindMenuBlur') || defaultSettings.keybindMenuBlur,
  799. keybindMenuOpaque: localStorage.getItem('keybindMenuOpaque') || defaultSettings.keybindMenuOpaque,
  800. keybindButtonsVisible: localStorage.getItem('keybindButtonsVisible') || defaultSettings.keybindButtonsVisible,
  801. keybindButtonOutline: localStorage.getItem('keybindButtonOutline') || defaultSettings.keybindButtonOutline,
  802. keybindButtonPositionX: localStorage.getItem('keybindButtonPositionX') || defaultSettings.keybindButtonPositionX,
  803. keybindButtonPositionY: localStorage.getItem('keybindButtonPositionY') || defaultSettings.keybindButtonPositionY,
  804. customCSS: localStorage.getItem('customCSS') || defaultSettings.customCSS, // Include custom CSS in export
  805. sliderColor: localStorage.getItem('sliderColor') || defaultSettings.sliderColor, // Include slider color in export
  806. };
  807.  
  808. const dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(settings));
  809. const downloadAnchorNode = document.createElement('a');
  810. downloadAnchorNode.setAttribute("href", dataStr);
  811. downloadAnchorNode.setAttribute("download", "keybind_settings.json");
  812. document.body.appendChild(downloadAnchorNode); // Required for Firefox
  813. downloadAnchorNode.click();
  814. downloadAnchorNode.remove();
  815. }
  816.  
  817. // Import Settings Function
  818. function importSettings(event) {
  819. const file = event.target.files[0];
  820. if (!file) {
  821. return;
  822. }
  823.  
  824. const reader = new FileReader();
  825. reader.onload = function(e) {
  826. const text = e.target.result;
  827. const settings = JSON.parse(text);
  828.  
  829. // Update localStorage with imported settings
  830. localStorage.setItem('keybindColors', JSON.stringify(settings.keybindColors));
  831. localStorage.setItem('keybindButtonSize', settings.keybindButtonSize);
  832. localStorage.setItem('keybindButtonOpacity', settings.keybindButtonOpacity);
  833. localStorage.setItem('keybindPressedColor', settings.keybindPressedColor);
  834. localStorage.setItem('keybindFontSize', settings.keybindFontSize);
  835. localStorage.setItem('keybindBorderThickness', settings.keybindBorderThickness);
  836. localStorage.setItem('keybindDarkMode', settings.keybindDarkMode);
  837. localStorage.setItem('keybindButtonShape', settings.keybindButtonShape);
  838. localStorage.setItem('keybindTheme', settings.keybindTheme);
  839. localStorage.setItem('keybindMenuBackground', settings.keybindMenuBackground);
  840. localStorage.setItem('keybindMenuBlur', settings.keybindMenuBlur);
  841. localStorage.setItem('keybindMenuOpaque', settings.keybindMenuOpaque);
  842. localStorage.setItem('keybindButtonsVisible', settings.keybindButtonsVisible);
  843. localStorage.setItem('keybindButtonOutline', settings.keybindButtonOutline);
  844. localStorage.setItem('keybindButtonPositionX', settings.keybindButtonPositionX);
  845. localStorage.setItem('keybindButtonPositionY', settings.keybindButtonPositionY);
  846. localStorage.setItem('customCSS', settings.customCSS); // Import custom CSS
  847. localStorage.setItem('sliderColor', settings.sliderColor); // Import slider color
  848.  
  849. // Reload the page to apply new settings
  850. window.location.reload();
  851. };
  852. reader.readAsText(file);
  853. }
  854.  
  855. // Event listener for Ctrl + O
  856. document.addEventListener('keydown', function(event) {
  857. if (event.ctrlKey && event.key === 'o') {
  858. event.preventDefault();
  859. colorMenuVisible = !colorMenuVisible;
  860. if (colorMenuVisible) {
  861. menu.style.display = 'grid';
  862. setTimeout(() => {
  863. menu.style.opacity = '1';
  864. menu.style.transform = 'translate(-50%, -50%) scale(1)';
  865. }, 10);
  866. } else {
  867. menu.style.opacity = '0';
  868. menu.style.transform = 'translate(-50%, -50%) scale(0.9)';
  869. setTimeout(() => {
  870. menu.style.display = 'none';
  871. }, 300);
  872. }
  873. }
  874. });
  875. });
  876. })();