Tools Menu

comfy tools menu (with everything you need)!

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey, Greasemonkey или Violentmonkey.

Для установки этого скрипта вам необходимо установить расширение, такое как Tampermonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Userscripts.

Чтобы установить этот скрипт, сначала вы должны установить расширение браузера, например Tampermonkey.

Чтобы установить этот скрипт, вы должны установить расширение — менеджер скриптов.

(у меня уже есть менеджер скриптов, дайте мне установить скрипт!)

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

(у меня уже есть менеджер стилей, дайте мне установить скрипт!)

// ==UserScript==
// @name         Tools Menu
// @namespace    https://tampermonkey.net/
// @version      beta-test-2
// @description  comfy tools menu (with everything you need)!
// @author       infynotarras328
// @match        https://arras.io/*
// @icon         https://www.svgrepo.com/show/489941/menu.svg
// @grant        none
// @run-at       document-start
// @license      MIT
// ==/UserScript==

(function () {
    'use strict';

    /*menu name               */const header = "Tools Menu";

    /*titles color            */const c1 = "#ffffff";
    /*titles outline color    */const c1o ="#484848";
    /*names color             */const c2 = "#ffffff";
    /*names outline color     */const c2o ="#484848";
 
    /*titles outline width    */const w1 = "1.5" ; // don't set them both more than 3 either it will look weird
    /*names outline width     */const w2 = "1.35";
 
    /*header font size        */const fH = "15px";
    /*titles font size        */const fT = "13px";
    /*buttons font size       */const fB = "12px";
 
    /*menu color              */const menuBG = "#a7a7af";
    /*borders color           */const border = "#484848";


    const buttons = {
        "General": [
            "Action 1",
            "Action 2",
            "Action 3",
            "Action 4",
            "Action 5",
            "Action 6",
            "Action 7",
        ],
        "Bypasses": [
            "Bypass 1",
            "Bypass 2",
            "Bypass 3",
        ],
        "Utilities": [
            "Utility 1",
            "Utility 2",
            "Utility 3",
            "Utility 4",
            "Utility 5",
            "Utility 6",
            "Utility 7",
            "Utility 8",
        ],
    };

    // hardcoded the outline :pfft::lmf::haha:
    const textShadow = `
      -${w1}px   -${w1}px ${c1o}, /* top left left */
    -${w1/2}px   -${w1}px ${c1o}, /* top left */
           0px   -${w1}px ${c1o}, /* top */
     ${w1/2}px   -${w1}px ${c1o}, /* top right */
       ${w1}px   -${w1}px ${c1o}, /* top right right */

       ${w1}px    ${w1}px ${c1o}, /* bottom right right */
     ${w1/2}px    ${w1}px ${c1o}, /* bottom right */
           0px    ${w1}px ${c1o}, /* bottom */
    -${w1/2}px    ${w1}px ${c1o}, /* bottom left */
      -${w1}px    ${w1}px ${c1o}, /* bottom left left */

       ${w1}px  ${w1/2}px ${c1o}, /* right top */
       ${w1}px        0px ${c1o}, /* right */
       ${w1}px -${w1/2}px ${c1o}, /* right bottom */

      -${w1}px  ${w1/2}px ${c1o}, /* left top */
      -${w1}px        0px ${c1o}, /* left */
      -${w1}px -${w1/2}px ${c1o}  /* left bottom */
        `;

    const textShadowNames = `
      -${w2}px   -${w2}px ${c2o}, /* top left left */
    -${w2/2}px   -${w2}px ${c2o}, /* top left */
           0px   -${w2}px ${c2o}, /* top */
     ${w2/2}px   -${w2}px ${c2o}, /* top right */
       ${w2}px   -${w2}px ${c2o}, /* top right right */

       ${w2}px    ${w2}px ${c2o}, /* bottom right right */
     ${w2/2}px    ${w2}px ${c2o}, /* bottom right */
           0px    ${w2}px ${c2o}, /* bottom */
    -${w2/2}px    ${w2}px ${c2o}, /* bottom left */
      -${w2}px    ${w2}px ${c2o}, /* bottom left left */

       ${w2}px  ${w2/2}px ${c2o}, /* right top */
       ${w2}px        0px ${c2o}, /* right */
       ${w2}px -${w2/2}px ${c2o}, /* right bottom */

      -${w2}px  ${w2/2}px ${c2o}, /* left top */
      -${w2}px        0px ${c2o}, /* left */
      -${w2}px -${w2/2}px ${c2o}  /* left bottom */
      `;






    // the menu
    const menu = document.createElement("div");
    menu.style.position = "fixed";
    menu.style.minWidth = "210px";
    menu.style.top = "1.2vw";
    menu.style.right = "1.2vw";
    menu.style.background = menuBG;
    menu.style.padding = "15px";

    menu.style.border = "solid";
    menu.style.borderRadius = "0%";
    menu.style.borderWidth = "5%";
    menu.style.borderColor = border;

    menu.style.pointerEvents = "none";
    menu.style.fontFamily = "Ubuntu";
    menu.style.fontSize = fH;
    menu.style.textAlign = "center";

    menu.style.transform = "translateX(135%)";
    menu.style.transition = "transform 0.5s ease";

    menu.style.cursor = "crosshair";
    menu.style.zIndex = "99999";
    menu.addEventListener("mousedown", (e) => {
        if (e.button === 1) e.preventDefault();
    });
    // remove the gayass scroll stripe by making its opacity and width a fucking zero
    const style = document.createElement('style');
    style.textContent = `
    #MenuScrolling::-webkit-scrollbar {
        width: 0px;
        background: transparent;
        }
    `;
    document.head.appendChild(style);

    // the title
    const title = document.createElement("div");
    title.textContent = header;
    title.style.textShadow = textShadow;
    title.style.textAlign = "center";
    title.style.color = c1;
    title.style.margin = "-4px 30px 20px 0px"
    title.style.fontWeight = "bold";
    menu.appendChild(title);


    // the button which makes the menu appear
    const revealBtn = document.createElement("div");
    revealBtn.textContent = "Tools Menu";
    revealBtn.style.position = "absolute";
    revealBtn.style.width = "130px";
    revealBtn.style.top = "1.2vw";
    revealBtn.style.right = "0vw";
    revealBtn.style.padding = "6px 0px";

    revealBtn.style.background = "#CFFFEF";
    revealBtn.style.border = "solid";
    revealBtn.style.borderRadius = "0%";
    revealBtn.style.borderWidth = "5%";
    revealBtn.style.borderColor = border;

    revealBtn.style.fontFamily = "Ubuntu";
    revealBtn.style.textAlign = "center";
    revealBtn.style.fontWeight = "bold";
    revealBtn.style.fontSize = "14px";
    revealBtn.style.textShadow = ` /* independent from other borders*/
        -1.5px    -1.5px ${border}, /* top left left */
        0.75px    -1.5px ${border}, /* top left */
           0px    -1.5px ${border}, /* top */
        0.75px    -1.5px ${border}, /* top right */
         1.5px    -1.5px ${border}, /* top right right */

         1.5px     1.5px ${border}, /* bottom right right */
        0.75px     1.5px ${border}, /* bottom right */
           0px     1.5px ${border}, /* bottom */
        0.75px     1.5px ${border}, /* bottom left */
        -1.5px     1.5px ${border}, /* bottom left left */

         1.5px    0.75px ${border}, /* right top */
         1.5px       0px ${border}, /* right */
         1.5px   -0.75px ${border}, /* right bottom */

        -1.5px    0.75px ${border}, /* left top */
        -1.5px       0px ${border}, /* left */
        -1.5px   -0.75px ${border}  /* left bottom */
        `;
    revealBtn.style.color = c1;

    revealBtn.style.cursor = "crosshair";
    revealBtn.style.zIndex = "0.2";

    // whatever that is, don't touch it since it gives a cool appearing animation
    revealBtn.style.transform = "translateX(100%)";
    setTimeout (() => {
        revealBtn.style.transform = "translateX(84%)";
    }, 100 );
    revealBtn.style.transition = "transform 0.5s ease";
    document.body.appendChild(revealBtn);

    // fuckass triangle on the button
    const revealBtn2 = document.createElement("div");
    revealBtn2.textContent = "🞀";
    revealBtn2.style.position = "fixed"
    revealBtn2.style.top = "0px";
    revealBtn2.style.right = (parseInt(revealBtn.style.width) - 21) + "px";

    revealBtn2.style.borderStyle = "none solid none none"; // make the border appear only on the right side
    revealBtn2.style.width = "18px";
    revealBtn2.style.height = "30px";
    revealBtn2.style.borderRadius = "0%";
    revealBtn2.style.borderWidth = "6px";
    revealBtn2.style.borderColor = border;

    revealBtn2.style.fontWeight = "bold";
    revealBtn2.style.fontSize = "20px";
    revealBtn2.style.textShadow = "0px 0px black";

    revealBtn.appendChild(revealBtn2);


    // red cross which makes the menu disappear
    const cross = document.createElement("div");
    cross.textContent = "✕";

    cross.style.position = "absolute";
    cross.style.top = "0%";
    cross.style.right = "0%";

    cross.style.borderStyle = "none none solid solid";
    cross.style.borderRadius = "0%";
    cross.style.borderWidth = "5%";
    cross.style.borderColor = border;
    cross.style.background = "#E03E41";

    cross.style.width = "30px";
    cross.style.height = "30px";
    cross.style.lineHeight = "30px";

    cross.style.fontSize = "24px";
    cross.style.fontFamily = "Ubuntu";
    cross.style.fontWeight = "bold";
    cross.style.textAlign = "center";

    cross.style.color = "#ffffff";
    cross.style.cursor = "crosshair";

    menu.appendChild(cross);



    // scrolling feature
    const groupsContainer = document.createElement("div");
    groupsContainer.style.maxHeight = "70vh"; // max 70% from the page zoom
    groupsContainer.style.overflowY = "auto"; // the buttons won't go out of the bounds
    groupsContainer.style.scrollBehavior = "smooth";
    groupsContainer.id = 'MenuScrolling';
    menu.appendChild(groupsContainer);



    // open button fuckery
    let menuOpen = false;
    let isAnimating = false;


    // lets the red cross work
    cross.onclick = () => {
        if (isAnimating || !menuOpen) return;
        isAnimating = true;
        menuOpen = false;

        menu.style.pointerEvents = "none";
        menu.style.transform = "translateX(135%)";

        revealBtn.style.transform = "translateX(84%)";

        setTimeout(() => {
            isAnimating = false;
        }, 400);
    };


    // makes the menu appear when you press the button
    revealBtn.onclick = () => {
        if (isAnimating || menuOpen) return;
        isAnimating = true;
        menuOpen = true;

        menu.style.pointerEvents = "auto";
        menu.style.transform = "translateX(0)";

        revealBtn.style.transform = "translateX(120%)";

        setTimeout(() => {
            isAnimating = false;
        }, 400);
    };


    // cool animation (hovering over the button makes it slide on the screen)
    revealBtn.addEventListener("mouseenter", () => {
        if (menuOpen) return;
        revealBtn.style.transform = "translateX(12%)";
    });

    revealBtn.addEventListener("mouseleave", () => {
        if (menuOpen) return;
        revealBtn.style.transform = "translateX(84%)";
    });


    function makeToggleAction(btn, config) {
        let enabled = false;
        const key = `arras_${btn.textContent}`;

        const updateColor = (state) => {
            btn.style.background = enabled
                ? colors["on" + state]
            : colors["off" + state];
        };

        const colors = {
            off: "#FFFFFF",
            offHover: "#757575",
            offDown: "#595959",

            on: "#B9E87E",
            onHover: "#C2EB91",
            onDown: "#595959"
        };

        // check localstorage upon load
        const saved = localStorage.getItem(key);
        if (saved === "1") {
            enabled = true;
            updateColor("");
            config[btn.textContent]?.Bon?.();
        } else {
            enabled = false;
            updateColor("");
        }

        btn.onmouseenter = () => updateColor("Hover");
        btn.onmouseleave = () => updateColor("");
        btn.onmousedown = () => updateColor("Down");
        btn.onmouseup = () => updateColor("Hover");

        btn.onclick = () => {
            const action = config[btn.textContent];
            if (!action) return;

            enabled = !enabled;
            updateColor("");
            localStorage.setItem(key, enabled ? "1" : "0"); // saving the button state

            if (enabled) action.Bon?.();
            else action.Boff?.();
        };

        updateColor("");
    }


    for (const groupName in buttons) {

        // group titles
        const groupTitle = document.createElement("div");
        groupTitle.textContent = groupName;
        groupTitle.style.color = c2;
        groupTitle.style.textShadow = textShadow;
        groupTitle.style.fontSize = fT;
        groupTitle.style.margin = "10px 3px 5px";
        groupTitle.style.textAlign = "left";
        groupTitle.style.fontWeight = "bold";
        groupsContainer.appendChild(groupTitle);

        // buttons
        buttons[groupName].forEach(name => {
            // buttons looks
            const btn = document.createElement("button");
            btn.textContent = name;
            btn.style.display = "block";
            btn.style.width = "100%";
            btn.style.height = "25px";
            btn.style.cursor = "crosshair";

            btn.style.border = "solid";
            btn.style.borderRadius = "2px";
            btn.style.borderWidth = "2%";
            btn.style.borderColor = border;
            btn.style.marginBottom = "2px";

            btn.style.fontFamily = "Ubuntu";
            btn.style.fontWeight = "bold";
            btn.style.fontSize = fB;
            btn.style.color = c2;
            btn.style.textShadow = textShadowNames;
            btn.style.background = "#FFFFFF";

            // cool color effects
            btn.onmouseenter = () => {btn.style.background = "#757575"}; // hovering
            btn.onmouseleave = () => {btn.style.background = "#FFFFFF"}; // not hovering
            btn.onmousedown = () => {btn.style.background = "#595959"}; // click down
            btn.onmouseup = () => {btn.style.background = "#757575"}; // click up

            revealBtn.onmouseenter = () => {revealBtn.style.background = "#D6FFF1"}; // hovering
            revealBtn.onmouseleave = () => {revealBtn.style.background = "#CFFFEF"}; // not hovering
            revealBtn.onmousedown = () => {revealBtn.style.background = "#99BAAE"}; // click down
            revealBtn.onmouseup = () => {revealBtn.style.background = "#D6FFF1"}; // click up

            cross.onmouseenter = () => {cross.style.background = "#E3595B"}; // hovering
            cross.onmouseleave = () => {cross.style.background = "#E03E41"}; // not hovering
            cross.onmousedown = () => {cross.style.background = "#A63335"}; // click down
            cross.onmouseup = () => {cross.style.background = "#E3595B"}; // click up

            makeToggleAction(btn, {
                "Action 1": {
                    Bon: () => {},
                    Boff: () => {},
                },
                "Action 2": {
                    Bon: () => {},
                    Boff: () => {},
                },
                "Action 3": {
                    Bon: () => {},
                    Boff: () => {},
                },
                "Action 4": {
                    Bon: () => {},
                    Boff: () => {},
                },
                "Action 5": {
                    Bon: () => {},
                    Boff: () => {},
                },
                "Action 6": {
                    Bon: () => {},
                    Boff: () => {},
                },
                "Action 7": {
                    Bon: () => {},
                    Boff: () => {},
                },

                "Bypass 1": {
                    Bon: () => {},
                    Boff: () => {},
                },
                "Bypass 2": {
                    Bon: () => {},
                    Boff: () => {},
                },
                "Bypass 3": {
                    Bon: () => {},
                    Boff: () => {},
                },

                "Utility 1": {
                    Bon: () => {},
                    Boff: () => {},
                },
                "Utility 2": {
                    Bon: () => {},
                    Boff: () => {},
                },
                "Utility 3": {
                    Bon: () => {},
                    Boff: () => {},
                },
                "Utility 4": {
                    Bon: () => {},
                    Boff: () => {},
                },
                "Utility 5": {
                    Bon: () => {},
                    Boff: () => {},
                },
                "Utility 6": {
                    Bon: () => {},
                    Boff: () => {},
                },
                "Utility 7": {
                    Bon: () => {},
                    Boff: () => {},
                },
                "Utility 8": {
                    Bon: () => {},
                    Boff: () => {},
                },
            });

            groupsContainer.appendChild(btn);
        });
    }
    document.body.appendChild(menu);
})();