您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Forces Drawaria's drawing controls to be always visible.
// ==UserScript== // @name Drawaria Drawing Controls (Always Visible) // @namespace http://tampermonkey.net/ // @version 1.0 // @description Forces Drawaria's drawing controls to be always visible. // @author YouTubeDrawaria // @match https://drawaria.online/* // @icon https://www.google.com/s2/favicons?sz=64&domain=drawaria.online // @grant none // @license MIT // ==/UserScript== (function() { 'use strict'; // --- Inyectar CSS para forzar la visibilidad y funcionalidad --- // Usamos !important para anular cualquier estilo inline o de media query const style = document.createElement('style'); style.innerHTML = ` #drawcontrols { display: flex !important; /* Asegura que el contenedor principal sea visible */ pointer-events: auto !important; /* Permite interacción con el ratón */ opacity: 1 !important; /* Asegura que no sea transparente */ /* Puedes ajustar la posición si se superpone con otros elementos Ejemplos: */ /* bottom: 0 !important; */ /* left: 50% !important; */ /* transform: translateX(-50%) !important; */ /* width: auto !important; */ } /* Asegurar que los botones dentro de drawcontrols también sean visibles y funcionales */ #drawcontrols .drawcontrols-button, #drawcontrols .drawcontrols-toolstoggle, #drawcontrols .drawcontrols-dialogbutton { display: flex !important; /* O flex si usan flexbox para alinear contenido */ pointer-events: auto !important; opacity: 1 !important; } /* Anular estilos de "deshabilitado" que el juego pueda aplicar */ #drawcontrols.drawcontrols-disabled, #drawcontrols .drawcontrols-button.drawcontrols-disabled { color: initial !important; /* Restablece el color normal */ pointer-events: auto !important; opacity: 1 !important; } /* Asegurar que el canvas sea interactivo */ #canvas { pointer-events: auto !important; } `; document.head.appendChild(style); // --- Lógica de dibujo local en el canvas --- const canvas = document.querySelector('#canvas'); if (canvas) { const ctx = canvas.getContext('2d'); let drawing = false; let lastX = 0; let lastY = 0; // Establecer propiedades de dibujo iniciales (se actualizarán con los controles) ctx.strokeStyle = '#000000'; // Color de línea por defecto (negro) ctx.lineWidth = 5; // Ancho de línea por defecto ctx.lineJoin = 'round'; // Tipo de unión de línea ctx.lineCap = 'round'; // Tipo de extremo de línea canvas.addEventListener('mousedown', (e) => { drawing = true; const rect = canvas.getBoundingClientRect(); lastX = e.clientX - rect.left; lastY = e.clientY - rect.top; ctx.beginPath(); ctx.moveTo(lastX, lastY); }); canvas.addEventListener('mousemove', (e) => { if (!drawing) return; const rect = canvas.getBoundingClientRect(); const currentX = e.clientX - rect.left; const currentY = e.clientY - rect.top; ctx.lineTo(currentX, currentY); ctx.stroke(); lastX = currentX; lastY = currentY; }); canvas.addEventListener('mouseup', () => { drawing = false; ctx.closePath(); }); canvas.addEventListener('mouseout', () => { if (drawing) { drawing = false; ctx.closePath(); } }); } else { console.warn("Drawaria Local Drawing Controls: Canvas element with ID 'canvas' not found."); } // --- Hacer que los controles de dibujo actualicen el contexto de dibujo LOCAL --- // Usamos MutationObserver para esperar a que jQuery esté disponible y los elementos del DOM se carguen. // También escuchamos los eventos click y input de los controles. const observer = new MutationObserver((mutations, obs) => { // Ejecutar solo si jQuery está cargado if (typeof jQuery === 'undefined') { return; } // Una vez que jQuery esté listo, podemos desconectar el observer si lo deseamos. // O lo mantenemos para capturar elementos que se puedan añadir dinámicamente. // Para este caso, lo mantendremos para mayor robustez con elementos dinámicos. const drawControls = jQuery('#drawcontrols'); if (drawControls.length === 0) { return; // Los controles aún no están en el DOM } // 1. Deshabilitar cualquier clase de "deshabilitado" que el juego pueda añadir dinámicamente drawControls.removeClass('drawcontrols-disabled'); drawControls.find('.drawcontrols-button').removeClass('drawcontrols-disabled'); // 2. Capturar clics en los botones de color drawControls.off('click.userScriptColors', '.drawcontrols-color').on('click.userScriptColors', '.drawcontrols-color', function(e) { e.stopPropagation(); // Evita que el evento llegue a los manejadores del juego e.preventDefault(); // Previene cualquier acción por defecto (como cambiar el cursor real del juego) const color = jQuery(this).css('background-color'); if (canvas && canvas.getContext) { canvas.getContext('2d').strokeStyle = color; console.log('Local drawing color changed to:', color); // Puedes añadir un feedback visual, como un borde al color seleccionado drawControls.find('.drawcontrols-color').css('border', ''); jQuery(this).css('border', '2px solid white'); } }); // 3. Capturar cambios en el slider de ancho de línea drawControls.off('input.userScriptWidth', '#drawwidthrange').on('input.userScriptWidth', '#drawwidthrange', function(e) { e.stopPropagation(); e.preventDefault(); const rangeValue = parseFloat(jQuery(this).val()); let lineWidth = 5; // Valor por defecto // Mapeo simple de los valores del rango a los tamaños del pincel de Drawaria // Basado en LINEWIDTHLIST=[5,12,45] en el JS del juego if (rangeValue <= 0.5) { lineWidth = 5; } else if (rangeValue <= 1.5) { lineWidth = 12; } else { lineWidth = 45; } if (canvas && canvas.getContext) { canvas.getContext('2d').lineWidth = lineWidth; console.log('Local drawing line width changed to:', lineWidth); } }); // 4. Implementar la funcionalidad de la goma de borrar (Eraser) // El botón de goma de borrar tiene la clase drawcontrols-button y el ícono fas fa-eraser drawControls.off('click.userScriptEraser', '.drawcontrols-button .fas.fa-eraser').on('click.userScriptEraser', '.drawcontrols-button .fas.fa-eraser', function(e) { e.stopPropagation(); e.preventDefault(); if (canvas && canvas.getContext) { const currentCtx = canvas.getContext('2d'); // Para borrar, podemos cambiar el color del trazo al color de fondo del canvas (blanco) currentCtx.strokeStyle = '#FFFFFF'; // Opcional: ajustar el ancho de la goma para que se note la diferencia currentCtx.lineWidth = 20; // Un ancho mayor para la goma console.log('Local drawing set to Eraser mode (white color).'); } }); // 5. Implementar la funcionalidad de Limpiar todo (Clear All) // El botón de limpiar todo tiene la clase drawcontrols-button y el ícono fas fa-trash-alt drawControls.off('click.userScriptClear', '.drawcontrols-button .fas.fa-trash-alt').on('click.userScriptClear', '.drawcontrols-button .fas.fa-trash-alt', function(e) { e.stopPropagation(); e.preventDefault(); if (canvas && canvas.getContext) { const currentCtx = canvas.getContext('2d'); currentCtx.clearRect(0, 0, canvas.width, canvas.height); // Limpiar todo el canvas console.log('Local canvas cleared.'); // Después de limpiar, restablecer el color a negro por defecto currentCtx.strokeStyle = '#000000'; currentCtx.lineWidth = 5; } }); // 6. Asegurar que los botones de toolstoggle (como el color picker o pressure settings) también sean visibles // Estos botones tienen la clase .drawcontrols-toolstoggle y .drawcontrols-dialogbutton drawControls.off('click.userScriptToggleTools', '.drawcontrols-toolstoggle, .drawcontrols-dialogbutton').on('click.userScriptToggleTools', '.drawcontrols-toolstoggle, .drawcontrols-dialogbutton', function(e) { // Permitimos la propagación para estos botones para que el juego pueda abrir sus modales/popups // Sin embargo, si quieres que *solo* sean visuales y no activen nada del juego, // puedes añadir e.stopPropagation() y e.preventDefault() aquí también. // Para "funcionales" en el sentido de que abran sus modales, no los bloqueamos. console.log('Tool toggle/dialog button clicked. Game\'s original handler might open a modal.'); }); // Desconectar el observer si ya hemos configurado todos los eventos principales. // Sin embargo, mantenerlo conectado puede ser útil si el juego reconstruye partes del DOM. // Para este script, lo dejaremos funcionando para que re-aplique los listeners si es necesario. // obs.disconnect(); }); // Iniciar el observer en el body para detectar cambios en el DOM observer.observe(document.body, { childList: true, subtree: true }); // Forzar la remoción de la clase 'drawcontrols-disabled' en la carga inicial y cada vez que aparezca // (Útil si el juego añade la clase después de que se carga el script) window.addEventListener('load', () => { const drawControlsElement = document.querySelector('#drawcontrols'); if (drawControlsElement) { drawControlsElement.classList.remove('drawcontrols-disabled'); } }); // Usar jQuery para asegurar que el 'drawcontrols' se muestre en cuanto se detecte. // Esto es un 'fallback' por si el observer no lo pilla a tiempo o si se usa jQuery en el juego. // Asegurarse de que jQuery esté cargado antes de intentar usarlo. if (typeof jQuery !== 'undefined') { jQuery(document).ready(function() { jQuery('#drawcontrols').css({ 'display': 'flex', 'pointer-events': 'auto', 'opacity': '1' }).removeClass('drawcontrols-disabled'); jQuery('#drawcontrols').find('.drawcontrols-button').removeClass('drawcontrols-disabled'); jQuery('#canvas').css('pointer-events', 'auto'); }); } })();