/* eslint-disable no-multi-spaces */ // ==UserScript== // @name Dynamic Image Scaler for TierMaker // @namespace https://gist.github.com/jesterjunk/ // @homepage https://gist.github.com/jesterjunk/6c9d59f326eb501b909c1e77ee942876 // @version 0 // @description Dynamically scale images using a slider (with scroll and arrow keys) on TierMaker. // @author a speck of dust on a tiny rock flying through a vast expanse of the universe // @match https://tiermaker.com/* // @icon https://www.google.com/s2/favicons?sz=64&domain=tiermaker.com // @grant none // @run-at document-end // ==/UserScript== /*╭────────────────────────────────────────────╮ Tested with Tampermonkey v5.1.1 Chrome Tampermonkey v5.3.3 Firefox ╰────────────────────────────────────────────╯*/ (function() { 'use strict'; // Helper function to wait until an element matching the selector exists function waitForElement(selector, callback) { const element = document.querySelector(selector); if (element) { callback(element); return; } const observer = new MutationObserver((mutations, observerInstance) => { const element = document.querySelector(selector); if (element) { observerInstance.disconnect(); callback(element); } }); observer.observe(document.body, { childList: true, subtree: true }); } // Create the main container for the slider and reset button const sliderContainer = document.createElement('div'); sliderContainer.style.position = "absolute"; sliderContainer.style.right = "0px"; sliderContainer.style.top = "calc(-37px - 34px)"; sliderContainer.style.display = "flex"; sliderContainer.style.flexDirection = "row"; sliderContainer.style.alignItems = "center"; sliderContainer.style.marginBottom = "10px"; sliderContainer.style.alignItems = "flex-end"; // Create the dimension label to display the element size const dimensionLabel = document.createElement('div'); dimensionLabel.style.marginBottom = "0"; dimensionLabel.style.fontSize = "14px"; dimensionLabel.style.fontWeight = "bold"; dimensionLabel.style.color = "#BFBFBF"; // Create a row container to hold the slider and the reset button side by side const sliderColumn = document.createElement('div'); sliderColumn.style.display = "flex"; sliderColumn.style.alignItems = "center"; sliderColumn.style.flexDirection = "column"; // Create the slider const slider = document.createElement('input'); slider.type = 'range'; slider.min = 1.0; slider.max = 3.75; slider.step = 0.05; slider.value = "1.0"; slider.style.accentColor = "#666"; // Check local storage for a saved slider value const savedScale = localStorage.getItem('tiermaker_slider_scale'); if (savedScale !== null) { slider.value = savedScale; } Object.assign(slider.style, { top: '10px', right: '10px', zIndex: 9999, cursor: 'pointer', opacity: '0.7' }); // Create the reset button const resetButton = document.createElement('button'); resetButton.textContent = 'Reset'; resetButton.style.marginLeft = '10px'; resetButton.style.zIndex = 9999; resetButton.style.fontSize = "11px"; resetButton.style.fontWeight = "bold"; resetButton.style.color = "#FFF"; resetButton.style.backgroundColor = "#000"; resetButton.style.border = "1px solid #666"; resetButton.style.padding = "4px"; resetButton.style.borderRadius = "4px"; resetButton.addEventListener('click', () => { localStorage.removeItem('tiermaker_slider_scale'); slider.value = 1.0; scaleElements(parseFloat(slider.value)); }); // Append the slider and reset button into the sliderColumn sliderColumn.appendChild(dimensionLabel); sliderColumn.appendChild(slider); // Append the dimension label and the sliderColumn into the main container sliderContainer.appendChild(sliderColumn); sliderContainer.appendChild(resetButton); // Insert the slider container before the tier container element const tierContainer = document.querySelector(`#tier-container`); tierContainer.before(sliderContainer); // Update the dimension label with the current element size function updateDimensionLabel() { const element = document.querySelector('.character'); if (element) { const element_width = getComputedStyle(element).width; const element_height = getComputedStyle(element).height; dimensionLabel.textContent = `${element_width.replace('px', '')} x ${element_height.replace('px', '')}`; } } // Scale the elements and update local storage function scaleElements(scaleFactor) { const elements = document.querySelectorAll('.character'); elements.forEach(elm => { const rect = elm.getBoundingClientRect(); elm.style.width = `${rect.width * scaleFactor / (elm._previousScale || 1)}px`; elm.style.height = `${rect.height * scaleFactor / (elm._previousScale || 1)}px`; elm._previousScale = scaleFactor; }); updateDimensionLabel(); // Save the current slider value to local storage localStorage.setItem('tiermaker_slider_scale', slider.value); } // Slider event listeners slider.addEventListener('input', () => { scaleElements(parseFloat(slider.value)); }); slider.addEventListener('wheel', (event) => { event.preventDefault(); const delta = Math.sign(event.deltaY); let newValue = parseFloat(slider.value) - delta * 0.1; newValue = Math.min(Math.max(newValue, slider.min), slider.max); slider.value = newValue.toFixed(2); scaleElements(parseFloat(slider.value)); }); slider.addEventListener('keydown', (event) => { if (event.key === 'ArrowLeft' || event.key === 'ArrowRight') { event.preventDefault(); let newValue = parseFloat(slider.value) + (event.key === 'ArrowRight' ? 0.1 : -0.1); newValue = Math.min(Math.max(newValue, slider.min), slider.max); slider.value = newValue.toFixed(2); scaleElements(parseFloat(slider.value)); } }); // Wait until the element with class 'character' exists before initial scaling waitForElement('.character', () => { scaleElements(parseFloat(slider.value)); }); })();