LAZER GRADIENT

Циклический градиент с эффектом "лазерного" перехода между цветами

Dovrai installare un'estensione come Tampermonkey, Greasemonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Userscripts per installare questo script.

Dovrai installare un'estensione come ad esempio Tampermonkey per installare questo script.

Dovrai installare un gestore di script utente per installare questo script.

(Ho già un gestore di script utente, lasciamelo installare!)

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

(Ho già un gestore di stile utente, lasciamelo installare!)

// ==UserScript==
// @name         LAZER GRADIENT
// @namespace    https://github.com/GothbreachHelper/
// @version      5.1
// @description  Циклический градиент с эффектом "лазерного" перехода между цветами
// @author       лазер дмитрий прайм
// @match        *://*/*
// @license      MIT
// @grant        none
// @icon         https://i.imgur.com/7X8kK9S.png
// ==/UserScript==

(function() {
    'use strict';

    // ████████████████████████████████████████████████████████████████████████████████████████████████████████████████████
    // █▄─█▀▀▀█─▄█─▄▄─█▄─▀█▀─▄█▄─▄▄▀█▄─▄█─▄▄─█─▄─▄─█▄─▄▄─█─▄▄─█▄─▄▄▀█─▄▄─█─▄▄▄▄█─▄─▄─█▄─▄▄─█▄─▀█▄─▄█─▄▄▄▄█─█─█▄─▄█─▄▄─█▄─▀█▀─▄█
    // ██─█─█─█─██─██─██─█▄█─███─▄─▄██─██─██─███─████─▄█▀█─██─██─▄─▄█─██─█▄▄▄▄─███─████─▄█▀██─█▄▀─██▄▄▄▄─█─▄─██─██─██─██─█▄█─██
    // ▀▀▄▄▄▀▄▄▄▀▄▄▄▄▀▄▄▄▀▄▄▄▀▄▄▀▄▄▀▄▄▄▀▄▄▄▄▀▀▄▄▄▀▀▄▄▄▄▄▀▄▄▄▄▀▄▄▀▄▄▀▄▄▄▄▀▄▄▄▄▄▀▀▄▄▄▀▀▄▄▄▄▄▀▄▄▄▀▀▄▄▀▄▄▄▄▄▀▄▀▄▀▄▄▄▀▄▄▄▄▀▄▄▄▀▄▄▄▀
    
    // Стили панели
    const panelStyle = `
        position: fixed;
        top: 100px;
        left: 100px;
        z-index: 99999;
        background: rgba(10,10,10,0.96);
        padding: 15px;
        border-radius: 8px;
        border: 2px solid #FF00FF;
        box-shadow: 0 0 25px rgba(255,0,255,0.7), 
                    inset 0 0 15px rgba(0,255,255,0.4);
        cursor: move;
        user-select: none;
        width: 240px;
        font-family: 'Courier New', monospace;
        backdrop-filter: blur(5px);
    `;

    const gradientStyle = `
        position: fixed;
        top: 0;
        left: 0;
        width: 100vw;
        height: 100vh;
        z-index: -1;
        pointer-events: none;
        opacity: 0;
        transition: opacity 1.5s cubic-bezier(0.4, 0, 0.2, 1);
    `;

    // Создаем элементы
    const panel = document.createElement("div");
    panel.style.cssText = panelStyle;
    panel.setAttribute('id', 'lazer-gradient-panel');

    const gradient = document.createElement("div");
    gradient.style.cssText = gradientStyle;
    gradient.setAttribute('id', 'lazer-gradient-effect');

    // █▀▀ █▀█ █▀▀ ▄▀█ ▀█▀ █ █▀█ █▄░█ █▀▀   █▀▀ █▀█ █▄░█ █▀▀ █░█ █▀ █▀▀ █▀▄   █▀▀ █▀▀ █▄░█ █▀▀ █▀█ ▄▀█ █▀▀ █▀▀ ▀█▀ █▀█ █▀█
    // █▄▄ █▀▄ ██▄ █▀█ ░█░ █ █▄█ █░▀█ ██▄   █▄▄ █▄█ █░▀█ █▄▄ █▄█ ▄█ ██▄ █▄▀   █▄█ ██▄ █░▀█ ██▄ █▀▄ █▀█ █▄▄ ██▄ ░█░ █▄█ █▀▄

    // [КОНТРОЛЛЕР СКОРОСТИ]
    let speed = 5;
    const speedControlHTML = `
    <div style="margin-bottom: 15px;">
        <div style="display: flex; justify-content: space-between; color: #00FFFF; font-size: 12px; margin-bottom: 5px;">
            <span>LAZER SPEED:</span>
            <span id="lazer-speed-value">${speed}</span>
        </div>
        <input type="range" min="1" max="10" value="${speed}" 
            style="width: 100%; accent-color: #FF00FF; cursor: pointer;"
            id="lazer-speed-slider">
    </div>`;

    // [ИНТЕРФЕЙС]
    panel.innerHTML = `
    <div style="border-bottom: 1px solid #FF00FF; margin-bottom: 15px; padding-bottom: 10px; display: flex; justify-content: space-between; align-items: center;">
        <div style="color: #00FFFF; font-weight: bold; text-shadow: 0 0 8px #FF00FF; font-size: 16px;">
            ⚡ LAZER GRADIENT v5.0
        </div>
        <div id="lazer-close-btn" style="color: white; cursor: pointer; font-size: 20px; transition: all 0.2s;">×</div>
    </div>

    <div id="lazer-color-container" style="display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-bottom: 15px; max-height: 250px; overflow-y: auto; padding-right: 5px;">
        <!-- Colors will be added here -->
    </div>

    <button id="lazer-add-color" style="background: rgba(255,0,255,0.2); color: white; border: 1px dashed #FF00FF; padding: 8px; border-radius: 5px; margin-bottom: 15px; cursor: pointer; width: 100%; font-size: 12px; transition: all 0.2s;">
        + ADD LAZER COLOR (MAX 10)
    </button>

    ${speedControlHTML}

    <button id="lazer-toggle-btn" style="background: linear-gradient(45deg, #FF00FF, #00FFFF); color: black; border: none; padding: 10px; border-radius: 5px; cursor: pointer; font-weight: bold; width: 100%; transition: all 0.3s; font-size: 14px; text-shadow: 0 0 3px rgba(255,255,255,0.5);">
        ACTIVATE LAZER
    </button>`;

    // █▀▀ █░█ █▀▀ █▀█ █▀▀ █▀▄   █▀▀ █▀█ █▄░█ █▀▀ █░█ █▀ █▀▀ █▀▄   █▀▀ █▀▀ █▄░█ █▀▀ █▀█ ▄▀█ █▀▀ █▀▀ ▀█▀ █▀█ █▀█
    // █▄▄ █▀█ ██▄ █▀▄ ██▄ █▄▀   █▄▄ █▄█ █░▀█ █▄▄ █▄█ ▄█ ██▄ █▄▀   █▄█ ██▄ █░▀█ ██▄ █▀▄ █▀█ █▄▄ ██▄ ░█░ █▄█ █▀▄

    // Инициализация
    document.body.appendChild(panel);
    document.body.appendChild(gradient);
    let isActive = false;
    let animationId = null;
    const colorInputs = [];
    let colorCount = 2;

    // Стартовые цвета
    const defaultColors = [
        '#FF00FF', '#00FFFF', '#00FF00', 
        '#FFFF00', '#FF0000', '#0000FF',
        '#FF8000', '#8000FF', '#0080FF',
        '#80FF00'
    ];

    // █▀▀ █ ▀█▀ █▀▀ █▀   █▀▀ █▀█ █▄░█ █▀▀ █░█ █▀ █▀▀ █▀▄   █▀▀ █▀▀ █▄░█ █▀▀ █▀█ ▄▀█ █▀▀ █▀▀ ▀█▀ █▀█ █▀█
    // █▀░ █ ░█░ ██▄ ▄█   █▄▄ █▄█ █░▀█ █▄▄ █▄█ ▄█ ██▄ █▄▀   █▄█ ██▄ █░▀█ ██▄ █▀▄ █▀█ █▄▄ ██▄ ░█░ █▄█ █▀▄

    // Функция создания цветового элемента
    function createColorElement(index) {
        const wrapper = document.createElement("div");
        wrapper.style.cssText = `
            display: flex;
            flex-direction: column;
            gap: 5px;
            align-items: center;
        `;

        const label = document.createElement("div");
        label.textContent = `LAZER ${index + 1}`;
        label.style.cssText = `
            color: #00FFFF;
            font-size: 10px;
            text-align: center;
            width: 100%;
            font-weight: bold;
        `;

        const inputWrapper = document.createElement("div");
        inputWrapper.style.cssText = `
            display: flex;
            align-items: center;
            gap: 5px;
            width: 100%;
            justify-content: center;
        `;

        const input = document.createElement("input");
        input.type = "color";
        input.value = defaultColors[index];
        input.style.cssText = `
            width: 30px;
            height: 30px;
            cursor: pointer;
            flex-shrink: 0;
            border: 1px solid #00FFFF;
            border-radius: 50%;
        `;

        const deleteBtn = document.createElement("div");
        deleteBtn.textContent = "×";
        deleteBtn.style.cssText = `
            color: white;
            cursor: pointer;
            font-size: 14px;
            opacity: ${index > 1 ? '0.7' : '0'};
            pointer-events: ${index > 1 ? 'auto' : 'none'};
            background: #FF00FF;
            width: 18px;
            height: 18px;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            transition: all 0.2s;
        `;

        // Добавляем обработчики
        input.addEventListener("change", updateGradient);
        deleteBtn.addEventListener("click", () => removeColor(index, wrapper));

        // Сохраняем ссылки
        colorInputs[index] = input;

        // Собираем компонент
        inputWrapper.appendChild(input);
        if (index > 1) inputWrapper.appendChild(deleteBtn);
        wrapper.appendChild(label);
        wrapper.appendChild(inputWrapper);
        
        return wrapper;
    }

    // Удаление цвета
    function removeColor(index, wrapper) {
        if (colorCount <= 2) return;
        
        colorContainer.removeChild(wrapper);
        colorInputs.splice(index, 1);
        colorCount--;
        
        // Перенумеровываем оставшиеся цвета
        const labels = colorContainer.querySelectorAll("div > div");
        labels.forEach((label, i) => {
            label.textContent = `LAZER ${i + 1}`;
        });
        
        if (isActive) updateGradient();
    }

    // █▀▀ █░█ █▀▀ █▀█ █▀▀ █▀▄   █▀▀ █▀█ █▄░█ █▀▀ █░█ █▀ █▀▀ █▀▄   █▀▀ █▀▀ █▄░█ █▀▀ █▀█ ▄▀█ █▀▀ █▀▀ ▀█▀ █▀█ █▀█
    // █▄▄ █▀█ ██▄ █▀▄ ██▄ █▄▀   █▄▄ █▄█ █░▀█ █▄▄ █▄█ ▄█ ██▄ █▄▀   █▄█ ██▄ █░▀█ ██▄ █▀▄ █▀█ █▄▄ ██▄ ░█░ █▄█ █▀▄

    // Обновление градиента
    function updateGradient() {
        if (colorInputs.length < 2) return;
        
        const colors = colorInputs.map(input => input.value);
        const extendedColors = [...colors, colors[0]]; // Замыкаем цикл
        
        cancelAnimationFrame(animationId);
        
        let progress = 0;
        const animate = () => {
            progress = (progress + (speed * 0.0005)) % 1;
            
            // Вычисляем текущие цвета
            const totalSegments = extendedColors.length - 1;
            const globalPos = progress * totalSegments;
            const segmentIndex = Math.floor(globalPos);
            const localProgress = globalPos - segmentIndex;
            
            const startColor = extendedColors[segmentIndex];
            const endColor = extendedColors[segmentIndex + 1];
            const currentColor = blendColors(startColor, endColor, localProgress);
            
            gradient.style.background = currentColor;
            animationId = requestAnimationFrame(animate);
        };
        
        animate();
    }

    // Смешивание цветов
    function blendColors(color1, color2, ratio) {
        const r1 = parseInt(color1.substring(1, 3), 16);
        const g1 = parseInt(color1.substring(3, 5), 16);
        const b1 = parseInt(color1.substring(5, 7), 16);
        
        const r2 = parseInt(color2.substring(1, 3), 16);
        const g2 = parseInt(color2.substring(3, 5), 16);
        const b2 = parseInt(color2.substring(5, 7), 16);
        
        const r = Math.round(r1 * (1 - ratio) + r2 * ratio);
        const g = Math.round(g1 * (1 - ratio) + g2 * ratio);
        const b = Math.round(b1 * (1 - ratio) + b2 * ratio);
        
        return `rgb(${r}, ${g}, ${b})`;
    }

    // █▀▀ █░█ █▀▀ █▀█ █▀▀ █▀▄   █▀▀ █▀█ █▄░█ █▀▀ █░█ █▀ █▀▀ █▀▄   █▀▀ █▀▀ █▄░█ █▀▀ █▀█ ▄▀█ █▀▀ █▀▀ ▀█▀ █▀█ █▀█
    // █▄▄ █▀█ ██▄ █▀▄ ██▄ █▄▀   █▄▄ █▄█ █░▀█ █▄▄ █▄█ ▄█ ██▄ █▄▀   █▄█ ██▄ █░▀█ ██▄ █▀▄ █▀█ █▄▄ ██▄ ░█░ █▄█ █▀▄

    // Инициализация интерфейса
    const colorContainer = panel.querySelector("#lazer-color-container");
    const addColorBtn = panel.querySelector("#lazer-add-color");
    const toggleBtn = panel.querySelector("#lazer-toggle-btn");
    const closeBtn = panel.querySelector("#lazer-close-btn");
    const speedSlider = panel.querySelector("#lazer-speed-slider");
    const speedValue = panel.querySelector("#lazer-speed-value");

    // Добавляем стартовые цвета
    for (let i = 0; i < 2; i++) {
        colorContainer.appendChild(createColorElement(i));
    }

    // █▀▀ █░█ █▀▀ █▀█ █▀▀ █▀▄   █▀▀ █▀█ █▄░█ █▀▀ █░█ █▀ █▀▀ █▀▄   █▀▀ █▀▀ █▄░█ █▀▀ █▀█ ▄▀█ █▀▀ █▀▀ ▀█▀ █▀█ █▀█
    // █▄▄ █▀█ ██▄ █▀▄ ██▄ █▄▀   █▄▄ █▄█ █░▀█ █▄▄ █▄█ ▄█ ██▄ █▄▀   █▄█ ██▄ █░▀█ ██▄ █▀▄ █▀█ █▄▄ ██▄ ░█░ █▄█ █▀▄

    // Обработчики событий
    addColorBtn.addEventListener("click", () => {
        if (colorCount >= 10) {
            alert("Maximum 10 LAZER colors!");
            return;
        }
        
        colorContainer.appendChild(createColorElement(colorCount));
        colorCount++;
    });

    toggleBtn.addEventListener("click", () => {
        if (colorInputs.length < 2) {
            alert("Need at least 2 LAZER colors!");
            return;
        }
        
        isActive = !isActive;
        
        if (isActive) {
            gradient.style.opacity = 0.85;
            toggleBtn.textContent = "DEACTIVATE LAZER";
            toggleBtn.style.background = "linear-gradient(45deg, #FF0000, #990000)";
            updateGradient();
        } else {
            gradient.style.opacity = 0;
            toggleBtn.textContent = "ACTIVATE LAZER";
            toggleBtn.style.background = "linear-gradient(45deg, #FF00FF, #00FFFF)";
            cancelAnimationFrame(animationId);
        }
    });

    speedSlider.addEventListener("input", () => {
        speed = parseInt(speedSlider.value);
        speedValue.textContent = speed;
        
        if (isActive) {
            cancelAnimationFrame(animationId);
            updateGradient();
        }
    });

    closeBtn.addEventListener("click", () => {
        panel.remove();
        gradient.remove();
        cancelAnimationFrame(animationId);
    });

    // Перетаскивание панели
    let isDragging = false;
    let dragOffset = { x: 0, y: 0 };

    panel.addEventListener("mousedown", (e) => {
        if (e.target.tagName !== "INPUT" && e.target !== closeBtn) {
            isDragging = true;
            dragOffset = {
                x: e.clientX - panel.getBoundingClientRect().left,
                y: e.clientY - panel.getBoundingClientRect().top
            };
            panel.style.cursor = "grabbing";
            panel.style.boxShadow = "0 0 30px rgba(255,0,255,1)";
        }
    });

    document.addEventListener("mousemove", (e) => {
        if (!isDragging) return;
        
        panel.style.left = `${e.clientX - dragOffset.x}px`;
        panel.style.top = `${e.clientY - dragOffset.y}px`;
    });

    document.addEventListener("mouseup", () => {
        isDragging = false;
        panel.style.cursor = "move";
        panel.style.boxShadow = "0 0 25px rgba(255,0,255,0.8)";
    });

    // Стили для скроллбара
    const scrollStyle = document.createElement("style");
    scrollStyle.textContent = `
        #lazer-color-container::-webkit-scrollbar {
            width: 4px;
            height: 4px;
        }
        #lazer-color-container::-webkit-scrollbar-thumb {
            background: #FF00FF;
            border-radius: 2px;
        }
        #lazer-color-container::-webkit-scrollbar-track {
            background: rgba(255,0,255,0.1);
        }
    `;
    document.head.appendChild(scrollStyle);

    console.log("⚡ LAZER GRADIENT v5.0 activated!");
})();