comfy tools menu (with everything you need)!
// ==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);
})();