您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Load Image Pokemon Name By HyperBeam and RenjiYuusei
// ==UserScript== // @name Image Names // @namespace http://tampermonkey.net/ // @version 5.0.1 // @description Load Image Pokemon Name By HyperBeam and RenjiYuusei // @run-at document-end // @author @HyperBeam & @RenjiYuusei // @match *://sangtacviet.vip/truyen/* // @license GPL-3.0 // @icon64 https://sangtacviet.vip/favicon.png // @grant GM_setValue // @grant GM_getValue // ==/UserScript== (function () { 'use strict'; //Chiều rộng bảng edit name STV const NAME_EDITOR_MOBILE_WIDTH = '100%'; const NAME_EDITOR_PC_WIDTH = '50%'; const STYLES = { '.pokemon-image': { width: '50px', height: '50px', }, '.pokemon-type': { width: '25px', height: '25px', }, '.pokemon-ball': { width: '35px', height: '35px', }, '.type': { fontWeight: 'bold', textShadow: '1px 1px 0 #222, -1px -1px 0 #222, 1px -1px 0 #222, -1px 1px 0 #222', }, 'i:has(img), i:has(span)': { whiteSpace: 'nowrap', }, 'i > img': { display: 'inline-block', marginTop: '-5px', }, '#configBox': { zIndex: '100', }, }; const TYPE_COLOR = { Normal: '#ededed', Fire: '#ff9236', Water: '#75d0ff', Electric: '#ffcd2c', Grass: '#70ffa2', Ice: '#4dffee', Fighting: '#ff4f61', Poison: '#ff4ae5', Ground: '#ebbb8a', Flying: '#c6d7ff', Psychic: '#ff9999', Bug: '#d7ff71', Rock: '#fff7bd', Ghost: '#a689ff', Dragon: '#6a90ff', Dark: '#dfd0ff', Steel: '#36c4d3', Fairy: '#ffa5e2', }; const BUTTON_STYLES = { fontSize: '14px', outline: 'none', borderRadius: '100%', height: '50px', width: '50px', marginBottom: '10px', cursor: 'pointer', border: '1px solid #ccc', backgroundColor: '#f0f0f0', transition: 'background-color 0.3s', }; const INPUT_STYLE = { width: '200px', height: '8px', borderRadius: '5px', outline: 'none', marginLeft: '5px', }; const RESIZE_INPUT_MIN_SIZE = 20; const RESIZE_INPUT_MAX_SIZE = 80; const RESIZE_INPUT_STEP = 10; const DEFAULT_CONFIG = { showCopyButton: true, showNamesButton: true, showReloadButton: true, showResizeInput: true, }; let config = { ...DEFAULT_CONFIG }; function loadConfig() { const savedConfig = GM_getValue('imageNamesConfig'); if (savedConfig) { config = { ...DEFAULT_CONFIG, ...JSON.parse(savedConfig) }; } } function saveConfig() { GM_setValue('imageNamesConfig', JSON.stringify(config)); } let imageSize = '50'; function loadImageSize() { const savedImageSize = GM_getValue('imageSize'); if (savedImageSize) { imageSize = JSON.parse(savedImageSize); } } function saveImageSize() { GM_setValue('imageSize', JSON.stringify(imageSize)); } function updateStyle() { STYLES['.pokemon-image'].width = imageSize; STYLES['.pokemon-image'].height = imageSize; } function applyStyles() { updateStyle(); document.querySelectorAll('i').forEach(tag => { if (/<img|<span/.test(tag.textContent)) { tag.innerHTML = tag.textContent; } }); Object.entries(STYLES).forEach(([selector, styles]) => { document.querySelectorAll(selector).forEach(element => { Object.assign(element.style, styles); }); }); Object.entries(TYPE_COLOR).forEach(([selector, color]) => { Array.from(document.getElementsByClassName(selector)).forEach(element => { element.style.color = color; }); }); } function createButton({ text, onClickFunction }) { const button = document.createElement('button'); Object.assign(button.style, BUTTON_STYLES); button.textContent = text; button.addEventListener('mouseover', () => (button.style.backgroundColor = '#e0e0e0')); button.addEventListener('mouseout', () => (button.style.backgroundColor = '#f0f0f0')); button.addEventListener('click', onClickFunction); return button; } function createInput({ name, type, event, handler }) { const input = document.createElement('input'); Object.assign(input.style, INPUT_STYLE); input.name = name; input.type = type; input.addEventListener(event, handler); return input; } function clickButton(selector) { document.querySelector(`button[onclick='${selector}']`)?.click(); } function createBoxMenu() { const boxMenu = document.createElement('div'); Object.assign(boxMenu.style, { position: 'fixed', bottom: '100px', right: '10px', display: 'flex', alignItems: 'end', flexDirection: 'column', zIndex: '1', width: '0', }); const buttons = [ { condition: 'showCopyButton', text: 'Copy', onClickFunction: copyToClipboard }, { condition: 'showNamesButton', text: 'Names', onClickFunction: () => clickButton('showNS()') }, { condition: 'showReloadButton', text: 'Reload', onClickFunction: () => clickButton('excute()') }, { condition: true, text: 'Config', onClickFunction: createConfigMenu }, ]; buttons.forEach(({ condition, ...props }) => { if (config[condition] || condition === true) { boxMenu.appendChild(createButton(props)); } }); if (config.showResizeInput) { const props = { name: 'resize', type: 'range', event: 'input', handler: event => { imageSize = event.target.value; saveImageSize(); applyStyles(); }, }; const input = createInput(props); const resizeInput = createResizeInput(input); boxMenu.appendChild(resizeInput); } document.body.appendChild(boxMenu); } function createResizeInput(input) { input.value = imageSize; input.min = RESIZE_INPUT_MIN_SIZE; input.max = RESIZE_INPUT_MAX_SIZE; input.step = RESIZE_INPUT_STEP; input.style.appearance = 'auto'; input.style.display = 'flex'; const dataList = document.createElement('datalist'); dataList.id = 'size-list'; for (let i = RESIZE_INPUT_MIN_SIZE; i <= RESIZE_INPUT_MAX_SIZE; i += RESIZE_INPUT_STEP) { const option = document.createElement('option'); option.value = i; dataList.appendChild(option); } input.setAttribute('list', 'size-list'); const resizeInput = document.createElement('label'); resizeInput.appendChild(document.createTextNode(`Resize:`)); resizeInput.appendChild(dataList); resizeInput.appendChild(input); return resizeInput; } async function copyToClipboard(e) { try { const copyText = document.querySelector('#namewd')?.value || ''; await navigator.clipboard.writeText(copyText); e.target.textContent = 'Copied!'; } catch (err) { e.target.textContent = 'Error!'; } finally { setTimeout(() => { e.target.textContent = 'Copy'; }, 2000); } } function createConfigMenu() { const modal = document.createElement('div'); Object.assign(modal.style, { position: 'fixed', top: '0', left: '0', width: '100%', height: '100%', backgroundColor: 'rgba(0, 0, 0, 0.5)', display: 'flex', justifyContent: 'center', alignItems: 'center', zIndex: '1000', }); const menuContent = document.createElement('div'); Object.assign(menuContent.style, { backgroundColor: 'white', padding: '20px', borderRadius: '10px', maxWidth: '300px', width: '90%', }); const title = document.createElement('h2'); title.textContent = 'Configuration'; title.style.marginTop = '0'; menuContent.appendChild(title); Object.keys(config).forEach(key => { const label = document.createElement('label'); label.style.display = 'block'; label.style.marginBottom = '10px'; const checkbox = document.createElement('input'); checkbox.type = 'checkbox'; checkbox.checked = config[key]; checkbox.id = key; checkbox.style.appearance = 'auto'; checkbox.addEventListener('change', e => { config[key] = e.target.checked; }); label.appendChild(checkbox); label.appendChild(document.createTextNode(' ' + createLabelName(key))); menuContent.appendChild(label); }); const buttonContainer = document.createElement('div'); buttonContainer.style.display = 'flex'; buttonContainer.style.justifyContent = 'space-between'; buttonContainer.style.marginTop = '20px'; const saveButton = createButton({ text: 'Save', onClickFunction: () => { saveConfig(); modal.remove(); location.reload(); }, }); saveButton.style.borderRadius = '5px'; saveButton.style.marginRight = '10px'; saveButton.style.flex = '1'; const cancelButton = createButton({ text: 'Cancel', onClickFunction: () => modal.remove() }); cancelButton.style.borderRadius = '5px'; cancelButton.style.flex = '1'; buttonContainer.appendChild(saveButton); buttonContainer.appendChild(cancelButton); menuContent.appendChild(buttonContainer); modal.appendChild(menuContent); document.body.appendChild(modal); } function createLabelName(key) { return key.replace(/([A-Z])/g, ' $1').replace(/^./, str => str.toUpperCase()); } function styleNameSettings() { const namewdf = document.querySelector('#namewdf'); const namewd = document.querySelector('#namewd'); if (window.innerWidth <= 600) { // Mobile styles namewdf.style.width = NAME_EDITOR_MOBILE_WIDTH; } else { // PC styles namewdf.style.width = NAME_EDITOR_PC_WIDTH; } Object.assign(namewd.style, { fontSize: '12px', lineHeight: '1.8', padding: '10px', outline: 'none', height: '60vh', }); } function autoReload() { const actions = [ "addSuperName('hv','z')", "addSuperName('hv','f')", "addSuperName('hv','s')", "addSuperName('hv','l')", "addSuperName('hv','a')", "addSuperName('el')", "addSuperName('vp')", "addSuperName('kn')", "addSuperName('el')", "addSuperName('hv','a')", 'saveNS();excute();', 'excute()', ]; actions.forEach(action => { const button = document.querySelector(`[onclick="${action}"]`); if (button) { button.addEventListener('click', applyStyles); } }); } function init() { loadConfig(); loadImageSize(); applyStyles(); createBoxMenu(); styleNameSettings(); autoReload(); } requestAnimationFrame(() => { setTimeout(init, 2000); }); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址