Gartic.io Custom Background

Replaces the default Gartic.io background with custom background.

La data de 24-06-2025. Vezi ultima versiune.

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

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

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

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

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

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         Gartic.io Custom Background
// @namespace    http://tampermonkey.net/
// @version      1.1
// @description  Replaces the default Gartic.io background with custom background.
// @author       arcticrevurne
// @icon         https://em-content.zobj.net/source/twitter/408/fox_1f98a.png
// @match        *://*.gartic.io/*
// @license      MIT
// @noframes
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    const defaultBackgroundColor = '#241500';
    const oldDefaultOrange = '#FF9800';

    function injectCustomCss() {
        const style = document.createElement('style');
        style.id = 'gartic-custom-styles';
        style.textContent = `
            #background::before {
                content: none !important;
                background-image: none !important;
                display: none !important;
                opacity: 0 !important;
            }
            body {
                background-color: ${defaultBackgroundColor} !important;
                /* Removed 'background-image: none !important;' from here */
            }
        `;
        document.head.appendChild(style);
    }

    function applyCustomBackground(value) {
        const body = document.querySelector('body');
        if (body) {
            if (value.startsWith('http://') || value.startsWith('https://') || value.startsWith('data:')) {
                body.style.backgroundImage = `url('${value}')`;
                body.style.backgroundSize = 'cover';
                body.style.backgroundRepeat = 'no-repeat';
                body.style.backgroundAttachment = 'fixed';
                body.style.backgroundPosition = 'center center';
                body.style.removeProperty('background-color');
            } else {
                body.style.backgroundImage = 'none';
                body.style.setProperty('background-color', value, 'important');
            }
        }
    }

    function resetBackground() {
        const body = document.querySelector('body');
        if (body) {
            body.style.backgroundImage = '';
            body.style.removeProperty('background-color');
        }
        localStorage.removeItem('gartic_custom_background');
    }

    function showNotification(message, isError = false) {
        const notificationArea = document.getElementById('gartic-bg-notification');
        if (!notificationArea) return;

        notificationArea.textContent = message;
        notificationArea.style.opacity = '1';
        notificationArea.style.backgroundColor = isError ? '#FF5722' : '#4CAF50';
        notificationArea.style.color = '#FFFFFF';
        notificationArea.style.padding = '8px';
        notificationArea.style.borderRadius = '4px';
        notificationArea.style.marginBottom = '10px';
        notificationArea.style.textAlign = 'center';

        setTimeout(() => {
            notificationArea.style.opacity = '0';
            notificationArea.style.padding = '0';
            notificationArea.style.marginBottom = '0';
        }, 3000);
    }

    function createSettingsMenu() {
        if (document.getElementById('gartic-custom-bg-menu')) {
            return;
        }

        const menuContainer = document.createElement('div');
        menuContainer.id = 'gartic-custom-bg-menu';
        menuContainer.style.position = 'fixed';
        menuContainer.style.top = '15px';
        menuContainer.style.right = '15px';
        menuContainer.style.backgroundColor = '#FFFFFF';
        menuContainer.style.border = '1px solid #FF9800';
        menuContainer.style.borderRadius = '6px';
        menuContainer.style.padding = '18px';
        menuContainer.style.zIndex = '99999';
        menuContainer.style.display = 'none';
        menuContainer.style.boxShadow = '0 4px 10px rgba(0, 0, 0, 0.15)';
        menuContainer.style.color = '#444444';
        menuContainer.style.fontFamily = 'Arial, sans-serif';
        menuContainer.style.maxWidth = '300px';
        menuContainer.style.width = '90%';

        const menuTitle = document.createElement('h3');
        menuTitle.textContent = 'Customise Background';
        menuTitle.style.marginBottom = '18px';
        menuTitle.style.color = '#FB8C00';
        menuTitle.style.textAlign = 'center';
        menuTitle.style.fontSize = '1.1em';
        menuTitle.style.fontWeight = '600';
        menuContainer.appendChild(menuTitle);

        const notificationArea = document.createElement('div');
        notificationArea.id = 'gartic-bg-notification';
        notificationArea.style.opacity = '0';
        notificationArea.style.transition = 'opacity 0.3s ease-in-out, padding 0.3s ease-in-out, margin-bottom 0.3s ease-in-out';
        notificationArea.style.overflow = 'hidden';
        notificationArea.style.maxHeight = '50px';
        menuContainer.appendChild(notificationArea);

        const fileInputLabel = document.createElement('label');
        fileInputLabel.textContent = 'Select Image File:';
        fileInputLabel.style.display = 'block';
        fileInputLabel.style.marginBottom = '6px';
        fileInputLabel.style.fontWeight = 'bold';
        fileInputLabel.style.fontSize = '0.9em';
        menuContainer.appendChild(fileInputLabel);

        const fileInput = document.createElement('input');
        fileInput.type = 'file';
        fileInput.accept = 'image/jpeg, image/png, image/gif';
        fileInput.style.width = '100%';
        fileInput.style.padding = '8px 0';
        fileInput.style.marginBottom = '15px';
        fileInput.style.backgroundColor = 'transparent';
        fileInput.style.border = 'none';
        fileInput.style.color = '#444444';
        fileInput.style.cursor = 'pointer';
        fileInput.style.fontSize = '0.9em';
        menuContainer.appendChild(fileInput);

        const divider = document.createElement('hr');
        divider.style.borderColor = '#FFCC80';
        divider.style.margin = '18px 0';
        menuContainer.appendChild(divider);

        const inputUrlLabel = document.createElement('label');
        inputUrlLabel.textContent = 'Or Enter Image URL or Hex Colour:';
        inputUrlLabel.style.display = 'block';
        inputUrlLabel.style.marginBottom = '6px';
        inputUrlLabel.style.fontWeight = 'bold';
        inputUrlLabel.style.fontSize = '0.9em';
        menuContainer.appendChild(inputUrlLabel);

        const imageUrlInput = document.createElement('input');
        imageUrlInput.type = 'text';
        imageUrlInput.placeholder = 'e.g., #FF9800 or https://example.com/image.jpg';
        imageUrlInput.style.width = 'calc(100% - 18px)';
        imageUrlInput.style.padding = '9px';
        imageUrlInput.style.marginBottom = '20px';
        imageUrlInput.style.backgroundColor = '#FFF3E0';
        imageUrlInput.style.border = '1px solid #FFB74D';
        imageUrlInput.style.borderRadius = '4px';
        imageUrlInput.style.color = '#444444';
        imageUrlInput.style.fontSize = '0.9em';
        menuContainer.appendChild(imageUrlInput);

        const buttonContainer = document.createElement('div');
        buttonContainer.style.display = 'flex';
        buttonContainer.style.justifyContent = 'space-between';
        buttonContainer.style.gap = '10px';
        menuContainer.appendChild(buttonContainer);

        const applyButton = document.createElement('button');
        applyButton.textContent = 'Apply';
        applyButton.style.flexGrow = '1';
        applyButton.style.backgroundColor = '#FF9800';
        applyButton.style.color = '#FFFFFF';
        applyButton.style.border = 'none';
        applyButton.style.padding = '10px 15px';
        applyButton.style.borderRadius = '5px';
        applyButton.style.cursor = 'pointer';
        applyButton.style.fontWeight = 'bold';
        applyButton.style.fontSize = '0.9em';
        applyButton.style.transition = 'background-color 0.2s ease, transform 0.1s ease, box-shadow 0.2s ease';
        applyButton.onmouseover = () => { applyButton.style.backgroundColor = '#F57C00'; applyButton.style.boxShadow = '0 2px 6px rgba(0,0,0,0.2)'; };
        applyButton.onmouseout = () => { applyButton.style.backgroundColor = '#FF9800'; applyButton.style.boxShadow = 'none'; };
        applyButton.onmousedown = () => applyButton.style.transform = 'scale(0.98)';
        applyButton.onmouseup = () => applyButton.style.transform = 'scale(1)';

        applyButton.onclick = () => {
            if (fileInput.files.length > 0) {
                const file = fileInput.files[0];
                const reader = new FileReader();
                reader.onloadend = function() {
                    const dataUrl = reader.result;
                    applyCustomBackground(dataUrl);
                    localStorage.setItem('gartic_custom_background', dataUrl);
                    showNotification('Background from file applied successfully!');
                };
                reader.onerror = function() {
                    showNotification('Failed to read file.', true);
                };
                reader.readAsDataURL(file);
            } else {
                const url = imageUrlInput.value.trim();
                if (url) {
                    applyCustomBackground(url);
                    localStorage.setItem('gartic_custom_background', url);
                    showNotification('Background from URL or colour applied successfully!');
                } else {
                    showNotification('Please select an image file or enter an image URL or hex colour.', true);
                }
            }
            fileInput.value = '';
            imageUrlInput.value = '';
        };
        buttonContainer.appendChild(applyButton);

        const resetButton = document.createElement('button');
        resetButton.textContent = 'Reset';
        resetButton.style.flexGrow = '1';
        resetButton.style.backgroundColor = '#FFB74D';
        resetButton.style.color = '#444444';
        resetButton.style.border = 'none';
        resetButton.style.padding = '10px 15px';
        resetButton.style.borderRadius = '5px';
        resetButton.style.cursor = 'pointer';
        resetButton.style.fontWeight = 'bold';
        resetButton.style.fontSize = '0.9em';
        resetButton.style.transition = 'background-color 0.2s ease, transform 0.1s ease, box-shadow 0.2s ease';
        resetButton.onmouseover = () => { resetButton.style.backgroundColor = '#FFA726'; resetButton.style.boxShadow = '0 2px 6px rgba(0,0,0,0.15)'; };
        resetButton.onmouseout = () => { resetButton.style.backgroundColor = '#FFB74D'; resetButton.style.boxShadow = 'none'; };
        resetButton.onmousedown = () => resetButton.style.transform = 'scale(0.98)';
        resetButton.onmouseup = () => resetButton.style.transform = 'scale(1)';

        resetButton.onclick = () => {
            resetBackground();
            imageUrlInput.value = '';
            fileInput.value = '';
            showNotification('Background has been reset to default.');
        };
        buttonContainer.appendChild(resetButton);

        document.body.appendChild(menuContainer);

        const menuToggleButton = document.createElement('button');
        menuToggleButton.textContent = '🖼️';
        menuToggleButton.style.position = 'fixed';
        menuToggleButton.style.top = '15px';
        menuToggleButton.style.right = '15px';
        menuToggleButton.style.backgroundColor = '#FF9800';
        menuToggleButton.style.color = '#FFFFFF';
        menuToggleButton.style.border = 'none';
        menuToggleButton.style.padding = '8px 14px';
        menuToggleButton.style.borderRadius = '5px';
        menuToggleButton.style.cursor = 'pointer';
        menuToggleButton.style.zIndex = '100000';
        menuToggleButton.style.boxShadow = '0 2px 5px rgba(0, 0, 0, 0.15)';
        menuToggleButton.style.fontWeight = 'bold';
        menuToggleButton.style.fontSize = '0.9em';
        menuToggleButton.style.transition = 'background-color 0.2s ease, transform 0.1s ease, box-shadow 0.2s ease';
        menuToggleButton.onmouseover = () => { menuToggleButton.style.backgroundColor = '#F57C00'; menuToggleButton.style.boxShadow = '0 3px 7px rgba(0,0,0,0.2)'; };
        menuToggleButton.onmouseout = () => { menuToggleButton.style.backgroundColor = '#FF9800'; menuToggleButton.style.boxShadow = '0 2px 5px rgba(0, 0, 0, 0.15)'; };
        menuToggleButton.onmousedown = () => menuToggleButton.style.transform = 'scale(0.98)';
        menuToggleButton.onmouseup = () => menuToggleButton.style.transform = 'scale(1)';

        menuToggleButton.onclick = (event) => {
            event.stopPropagation();
            if (menuContainer.style.display === 'none') {
                menuContainer.style.display = 'block';
                imageUrlInput.value = '';
                fileInput.value = '';
                notificationArea.style.opacity = '0';
                notificationArea.style.padding = '0';
                notificationArea.style.marginBottom = '0';
            } else {
                menuContainer.style.display = 'none';
            }
        };
        document.body.appendChild(menuToggleButton);

        document.addEventListener('click', (event) => {
            if (menuContainer.style.display === 'block' &&
                !menuContainer.contains(event.target) &&
                !menuToggleButton.contains(event.target)) {
                menuContainer.style.display = 'none';
            }
        });
    }

    injectCustomCss();

    let savedBackground = localStorage.getItem('gartic_custom_background');
    if (!savedBackground || savedBackground === oldDefaultOrange) {
        applyCustomBackground(defaultBackgroundColor);
        localStorage.setItem('gartic_custom_background', defaultBackgroundColor);
    } else {
        applyCustomBackground(savedBackground);
    }

    const observer = new MutationObserver((mutationsList, observer) => {
        const garticCoreElement = document.querySelector('.main-menu') || document.querySelector('.game-container') || document.body;

        if (garticCoreElement) {
            createSettingsMenu();
            observer.disconnect();
        } else if (document.body && !document.getElementById('gartic-custom-bg-menu')) {
            setTimeout(() => {
                if (!document.getElementById('gartic-custom-bg-menu')) {
                    createSettingsMenu();
                }
            }, 1000);
            observer.disconnect();
        }
    });

    observer.observe(document.body, { childList: true, subtree: true });

    document.addEventListener('DOMContentLoaded', () => {
        if (!document.getElementById('gartic-custom-bg-menu')) {
            setTimeout(createSettingsMenu, 1500);
        }
    });

})();