Drawaria Canvas Expander Toggle

Adds a toggle menu to expand/collapse the drawing canvas on Drawaria.online by hiding/showing side panels, and expands the canvas.

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Drawaria Canvas Expander Toggle
// @namespace    http://tampermonkey.net/
// @version      2025-05-23.3 // Incremented version to reflect this crucial fix
// @description  Adds a toggle menu to expand/collapse the drawing canvas on Drawaria.online by hiding/showing side panels, and expands the canvas.
// @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';

    const LS_KEY = 'drawaria_expand_canvas_v2'; // localStorage key for state persistence

    // --- Helper function to apply/remove canvas expansion styles ---
    function setCanvasExpanded(isExpanded) {
        const leftbar = document.getElementById('leftbar');
        const rightbar = document.getElementById('rightbar');
        const canvas = document.getElementById('canvas'); // The actual canvas element

        // Ensure main game elements are present before attempting modifications
        if (!leftbar || !rightbar || !canvas) {
            console.warn("Drawaria core elements (leftbar, rightbar, canvas) not found for expansion/collapse. Will re-attempt when elements are ready.");
            return false; // Indicate that elements were not ready
        }

        if (isExpanded) {
            // Apply styles to hide panels
            leftbar.style.display = 'none';
            rightbar.style.display = 'none';

            // Make the canvas element expand to fill the available flex space
            canvas.style.flexGrow = '1';
            canvas.style.width = 'auto'; // Important for flex items to allow growth
            console.log("Canvas expanded.");
        } else {
            // Restore original styles by clearing inline styles
            leftbar.style.display = '';
            rightbar.style.display = '';

            // Remove flex-grow and width to restore original canvas size
            canvas.style.flexGrow = '';
            canvas.style.width = '';
            console.log("Canvas collapsed.");
        }

        // Trigger a window resize event. This is crucial for Drawaria to re-render
        // its canvas based on the new available space.
        window.dispatchEvent(new Event('resize'));
        localStorage.setItem(LS_KEY, isExpanded ? 'true' : 'false'); // Save state
        return true; // Indicate successful application
    }

    // --- Inject custom UI (Button and Menu) and its CSS ---
    function injectUI() {
        // Inject CSS for the custom UI elements to make them look integrated
        const style = document.createElement('style');
        style.type = 'text/css';
        style.innerHTML = `
            #drawaria-custom-menu-container {
                position: absolute;
                top: 5px; /* Position from the top of the viewport */
                right: 180px; /* Adjust this value to place it appropriately relative to other top-right elements */
                z-index: 10000; /* Ensure it's on top of other elements */
                font-family: 'Open Sans', Arial, sans-serif; /* Try to match Drawaria's font */
                color: #333;
            }

            #drawaria-menu-toggle-button {
                background-color: #f1f9f5; /* Light background, similar to Drawaria's panels */
                border: 1px solid #b0b5b9; /* Soft border */
                border-radius: 5px;
                padding: 5px 10px;
                cursor: pointer;
                font-size: 14px;
                display: flex;
                align-items: center;
                gap: 6px; /* Space between icon and text */
                box-shadow: 0 1px 3px rgba(0,0,0,0.1); /* Subtle shadow */
                transition: background-color 0.2s ease; /* Smooth hover effect */
                white-space: nowrap; /* Prevent text wrapping */
            }

            #drawaria-menu-toggle-button:hover {
                background-color: #e0e0e0; /* Slightly darker on hover */
            }

            #drawaria-menu-toggle-button span {
                font-size: 16px; /* Icon size */
            }

            #drawaria-menu-content {
                display: none; /* Hidden by default */
                position: absolute;
                background-color: #f1f9f5;
                border: 1px solid #b0b5b9;
                border-radius: 5px;
                padding: 10px;
                top: 40px; /* Position just below the toggle button */
                right: 0;
                min-width: 180px; /* Ensure enough width for text */
                box-shadow: 0 2px 8px rgba(0,0,0,0.2);
            }

            #drawaria-menu-content.visible {
                display: block; /* Make visible when 'visible' class is added */
            }

            #drawaria-menu-content label {
                display: flex;
                align-items: center;
                cursor: pointer;
                font-size: 14px;
                margin-bottom: 0; /* No extra margin if only one item */
            }

            #drawaria-menu-content input[type="checkbox"] {
                margin-right: 8px;
                transform: scale(1.2); /* Make checkbox slightly larger for easier clicking */
            }
        `;
        document.head.appendChild(style); // Add CSS to the document's head

        // Inject HTML for the button and menu into the body
        const uiHtml = `
            <div id="drawaria-custom-menu-container">
                <button id="drawaria-menu-toggle-button" title="Toggle Canvas Expansion">
                    <span>🖼️</span> Canvas Options
                </button>
                <div id="drawaria-menu-content">
                    <label>
                        <input type="checkbox" id="expandCanvasCheckbox"> Expand Drawing Area
                    </label>
                </div>
            </div>
        `;
        document.body.insertAdjacentHTML('beforeend', uiHtml); // Insert at the end of the body

        // --- Get references to the injected UI elements ---
        const menuContainer = document.getElementById('drawaria-custom-menu-container');
        const toggleButton = document.getElementById('drawaria-menu-toggle-button');
        const menuContent = document.getElementById('drawaria-menu-content');
        const expandCanvasCheckbox = document.getElementById('expandCanvasCheckbox');

        if (!menuContainer || !toggleButton || !menuContent || !expandCanvasCheckbox) {
            console.error("Failed to find Drawaria custom UI elements after injection.");
            return;
        }

        // --- Add Event Listeners ---
        // Toggle the visibility of the menu content when the button is clicked
        toggleButton.addEventListener('click', (event) => {
            event.stopPropagation(); // Prevent document click listener from immediately closing it
            menuContent.classList.toggle('visible');
        });

        // Hide the menu when a click occurs outside of it
        document.addEventListener('click', (event) => {
            if (!menuContainer.contains(event.target)) {
                menuContent.classList.remove('visible');
            }
        });

        // Listen for changes on the "Expand Canvas" checkbox
        expandCanvasCheckbox.addEventListener('change', () => {
            setCanvasExpanded(expandCanvasCheckbox.checked);
        });

        // --- Initialize state from localStorage and apply when game is ready ---
        const storedState = localStorage.getItem(LS_KEY);
        const initialState = storedState === 'true';

        expandCanvasCheckbox.checked = initialState; // Set checkbox state visually

        // Use a MutationObserver to wait for the #main element to become visible,
        // which indicates the game content (leftbar, rightbar, canvas) is ready.
        const observer = new MutationObserver((mutationsList, observerInstance) => {
            const mainDiv = document.getElementById('main');
            // Check if mainDiv exists and its display style is not 'none'
            if (mainDiv && mainDiv.style.display !== 'none') {
                console.log("#main element became visible. Attempting to apply initial canvas state.");
                // Attempt to apply the state. setCanvasExpanded will internally check for sub-elements.
                if (setCanvasExpanded(initialState)) { // Only disconnect if successful
                    observerInstance.disconnect(); // Disconnect observer once the state is applied successfully
                }
                // If setCanvasExpanded returns false (elements not ready), the observer will continue
                // watching for other changes, which might involve the elements becoming available.
            }
        });

        // Start observing the document body for changes, looking for #main to become visible.
        // A small delay helps ensure this observer setup runs slightly after initial DOM render
        // to avoid conflicts or race conditions with the page's own JS.
        setTimeout(() => {
            observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style'] });
            // Also, make an immediate check in case the main content is already loaded/visible
            const mainDiv = document.getElementById('main');
            if (mainDiv && mainDiv.style.display !== 'none') {
                console.log("Immediate check: #main already visible. Attempting to apply initial canvas state.");
                if (setCanvasExpanded(initialState)) {
                     observer.disconnect();
                }
            }
        }, 500); // Wait 500ms before starting observation

        // Fallback for window.load just in case, this could also apply the state if observers somehow missed it.
        window.addEventListener('load', () => {
            const mainDiv = document.getElementById('main');
            if (mainDiv && mainDiv.style.display !== 'none') {
                console.log("Window loaded and #main is visible (fallback). Applying initial canvas state.");
                setCanvasExpanded(initialState);
                observer.disconnect(); // Ensure observer is stopped if fallback works
            }
        });
    }

    // Execute the UI injection function once the DOM is ready (or shortly after)
    // Using DOMContentLoaded for quicker UI appearance, but the core canvas expansion
    // logic will wait for the game's #main div to be truly ready.
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', injectUI);
    } else {
        injectUI();
    }

})();