mirror of
https://github.com/SwingTheVine/Wplace-BlueMarble.git
synced 2026-03-11 17:15:38 +00:00
Finished minimization for BM windows
This commit is contained in:
parent
1596a8d158
commit
9fb9e14d06
13 changed files with 680 additions and 529 deletions
101
dist/BlueMarble-For-GreasyFork.user.css
vendored
101
dist/BlueMarble-For-GreasyFork.user.css
vendored
|
|
@ -1,4 +1,105 @@
|
|||
/* src/overlay.css */
|
||||
.bm-window {
|
||||
position: fixed;
|
||||
background-color: rgba(21, 48, 99, 0.9);
|
||||
color: white;
|
||||
padding: 10px;
|
||||
border-radius: 8px;
|
||||
z-index: 9000;
|
||||
transition: all 0.3s ease, transform 0s;
|
||||
max-width: 300px;
|
||||
width: auto;
|
||||
font-family:
|
||||
"Roboto Mono",
|
||||
"Courier New",
|
||||
"Monaco",
|
||||
"DejaVu Sans Mono",
|
||||
monospace,
|
||||
"Arial";
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
.bm-dragbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: space-between;
|
||||
gap: 0.5ch;
|
||||
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="5" height="5"><circle cx="3" cy="3" r="1.5" fill="CornflowerBlue" /></svg>') repeat;
|
||||
cursor: grab;
|
||||
width: 100%;
|
||||
height: fit-content;
|
||||
}
|
||||
.bm-dragbar.bm-dragging {
|
||||
cursor: grabbing;
|
||||
}
|
||||
.bm-window:has(.bm-dragbar.bm-dragging) {
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
}
|
||||
.bm-dragbar.bm-dragging {
|
||||
pointer-events: auto;
|
||||
}
|
||||
.bm-favicon {
|
||||
display: inline-block;
|
||||
height: 2.5em;
|
||||
margin-right: 1ch;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.bm-window h1 {
|
||||
display: inline-block;
|
||||
font-size: x-large;
|
||||
font-weight: bold;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.bm-dragbar h1 {
|
||||
font-size: 1.2em;
|
||||
margin-left: 0.5ch;
|
||||
user-select: none;
|
||||
text-shadow:
|
||||
3px 0px rgba(21, 48, 99, 0.5),
|
||||
-3px 0px rgba(21, 48, 99, 0.5),
|
||||
0px 3px rgba(21, 48, 99, 0.5),
|
||||
0px -3px rgba(21, 48, 99, 0.5),
|
||||
3px 3px rgba(21, 48, 99, 0.5),
|
||||
-3px 3px rgba(21, 48, 99, 0.5),
|
||||
3px -3px rgba(21, 48, 99, 0.5),
|
||||
-3px -3px rgba(21, 48, 99, 0.5);
|
||||
}
|
||||
.bm-container {
|
||||
margin: 0.5em 0;
|
||||
}
|
||||
.bm-window button {
|
||||
background-color: #144eb9;
|
||||
border-radius: 1em;
|
||||
padding: 0 0.75ch;
|
||||
}
|
||||
.bm-window button:hover,
|
||||
.bm-window button:focus-visible {
|
||||
background-color: #1061e5;
|
||||
}
|
||||
.bm-window button:active .bm-window button:disabled {
|
||||
background-color: #2e97ff;
|
||||
}
|
||||
.bm-window button:disabled,
|
||||
.bm-window button:disabled {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
.bm-button-circle {
|
||||
border: white 1px solid;
|
||||
height: 1.5em;
|
||||
width: 1.5em;
|
||||
margin-top: 2px;
|
||||
text-align: center;
|
||||
line-height: 1em;
|
||||
padding: 0 !important;
|
||||
}
|
||||
.bm-window-content {
|
||||
overflow: hidden;
|
||||
transition: height 300ms cubic-bezier(.4, 0, .2, 1);
|
||||
}
|
||||
#bm-overlay,
|
||||
#bm-overlay-telemetry {
|
||||
position: fixed;
|
||||
|
|
|
|||
301
dist/BlueMarble-For-GreasyFork.user.js
vendored
301
dist/BlueMarble-For-GreasyFork.user.js
vendored
|
|
@ -2,7 +2,7 @@
|
|||
// @name Blue Marble
|
||||
// @name:en Blue Marble
|
||||
// @namespace https://github.com/SwingTheVine/
|
||||
// @version 0.88.95
|
||||
// @version 0.88.122
|
||||
// @description A userscript to automate and/or enhance the user experience on Wplace.live. Make sure to comply with the site's Terms of Service, and rules! This script is not affiliated with Wplace.live in any way, use at your own risk. This script is not affiliated with TamperMonkey. The author of this userscript is not responsible for any damages, issues, loss of data, or punishment that may occur as a result of using this script. This script is provided "as is" under the MPL-2.0 license. The "Blue Marble" icon is licensed under CC0 1.0 Universal (CC0 1.0) Public Domain Dedication. The image is owned by NASA.
|
||||
// @description:en A userscript to automate and/or enhance the user experience on Wplace.live. Make sure to comply with the site's Terms of Service, and rules! This script is not affiliated with Wplace.live in any way, use at your own risk. This script is not affiliated with TamperMonkey. The author of this userscript is not responsible for any damages, issues, loss of data, or punishment that may occur as a result of using this script. This script is provided "as is" under the MPL-2.0 license. The "Blue Marble" icon is licensed under CC0 1.0 Universal (CC0 1.0) Public Domain Dedication. The image is owned by NASA.
|
||||
// @author SwingTheVine
|
||||
|
|
@ -169,6 +169,52 @@
|
|||
callback(this, small);
|
||||
return this;
|
||||
}
|
||||
/** Adds a `details` to the overlay.
|
||||
* This `details` element will have properties shared between all `details` elements in the overlay.
|
||||
* You can override the shared properties by using a callback.
|
||||
* @param {Object.<string, any>} [additionalProperties={}] - The DOM properties of the `details` that are NOT shared between all overlay `details` elements. These should be camelCase.
|
||||
* @param {function(Overlay, HTMLParagraphElement):void} [callback=()=>{}] - Additional JS modification to the `details`.
|
||||
* @returns {Overlay} Overlay class instance (this)
|
||||
* @since 0.88.96
|
||||
* @example
|
||||
* // Assume all <details> elements have a shared class (e.g. {'className': 'bar'})
|
||||
* overlay.addDetails({'id': 'foo'}).buildOverlay(document.body);
|
||||
* // Output:
|
||||
* // (Assume <body> already exists in the webpage)
|
||||
* <body>
|
||||
* <details id="foo" class="bar"></details>
|
||||
* </body>
|
||||
*/
|
||||
addDetails(additionalProperties = {}, callback = () => {
|
||||
}) {
|
||||
const properties = {};
|
||||
const details = __privateMethod(this, _Overlay_instances, createElement_fn).call(this, "details", properties, additionalProperties);
|
||||
callback(this, details);
|
||||
return this;
|
||||
}
|
||||
/** Adds a `summary` to the overlay.
|
||||
* This `summary` element will have properties shared between all `summary` elements in the overlay.
|
||||
* You can override the shared properties by using a callback.
|
||||
* @param {Object.<string, any>} [additionalProperties={}] - The DOM properties of the `summary` that are NOT shared between all overlay `summary` elements. These should be camelCase.
|
||||
* @param {function(Overlay, HTMLParagraphElement):void} [callback=()=>{}] - Additional JS modification to the `summary`.
|
||||
* @returns {Overlay} Overlay class instance (this)
|
||||
* @since 0.88.96
|
||||
* @example
|
||||
* // Assume all <summary> elements have a shared class (e.g. {'className': 'bar'})
|
||||
* overlay.addSummary({'id': 'foo', 'textContent': 'Foobar.'}).buildOverlay(document.body);
|
||||
* // Output:
|
||||
* // (Assume <body> already exists in the webpage)
|
||||
* <body>
|
||||
* <summary id="foo" class="bar">Foobar.</summary>
|
||||
* </body>
|
||||
*/
|
||||
addSummary(additionalProperties = {}, callback = () => {
|
||||
}) {
|
||||
const properties = {};
|
||||
const summary = __privateMethod(this, _Overlay_instances, createElement_fn).call(this, "summary", properties, additionalProperties);
|
||||
callback(this, summary);
|
||||
return this;
|
||||
}
|
||||
/** Adds a `img` to the overlay.
|
||||
* This `img` element will have properties shared between all `img` elements in the overlay.
|
||||
* You can override the shared properties by using a callback.
|
||||
|
|
@ -619,10 +665,10 @@
|
|||
this.currentParent = element;
|
||||
}
|
||||
for (const [property, value] of Object.entries(properties)) {
|
||||
element[property] = value;
|
||||
element[property != "class" ? property : "className"] = value;
|
||||
}
|
||||
for (const [property, value] of Object.entries(additionalProperties)) {
|
||||
element[property] = value;
|
||||
element[property != "class" ? property : "className"] = value;
|
||||
}
|
||||
return element;
|
||||
};
|
||||
|
|
@ -1112,6 +1158,7 @@ Getting Y ${pixelY}-${pixelY + drawSizeY}`);
|
|||
const matchingTileBlobs = matchingTiles.map((tile) => {
|
||||
const coords2 = tile.split(",");
|
||||
return {
|
||||
instance: template,
|
||||
bitmap: template.chunked[tile],
|
||||
chunked32: template.chunked32?.[tile],
|
||||
tileCoords: [coords2[0], coords2[1]],
|
||||
|
|
@ -1154,11 +1201,10 @@ Version: ${this.version}`);
|
|||
for (const template of templatesToDraw) {
|
||||
console.log(`Template:`);
|
||||
console.log(template);
|
||||
let templateBeforeFilter32 = template.chunked32;
|
||||
const coordXtoDrawAt = Number(template.pixelCoords[0]) * this.drawMult;
|
||||
const coordYtoDrawAt = Number(template.pixelCoords[1]) * this.drawMult;
|
||||
context.drawImage(template.bitmap, coordXtoDrawAt, coordYtoDrawAt);
|
||||
let templateBeforeFilter32 = template.chunked32;
|
||||
console.log("TemplateBeforeFilter32: ", templateBeforeFilter32);
|
||||
if (!templateBeforeFilter32) {
|
||||
const templateBeforeFilter = context.getImageData(coordXtoDrawAt, coordYtoDrawAt, template.bitmap.width, template.bitmap.height);
|
||||
templateBeforeFilter32 = new Uint32Array(templateBeforeFilter.data.buffer);
|
||||
|
|
@ -1175,6 +1221,7 @@ Version: ${this.version}`);
|
|||
}
|
||||
console.log(`Finished calculating correct pixels for the tile ${tileCoords} in ${(Date.now() - timer) / 1e3} seconds!
|
||||
There are ${pixelsCorrectTotal} correct pixels.`);
|
||||
template.instance.pixelCount["correct"] = pixelsCorrect;
|
||||
}
|
||||
return await canvas.convertToBlob({ type: "image/png" });
|
||||
}
|
||||
|
|
@ -1645,225 +1692,37 @@ Time Since Blink: ${String(Math.floor(elapsed / 6e4)).padStart(2, "0")}:${String
|
|||
observer.observe(document.body, { childList: true, subtree: true });
|
||||
}
|
||||
function buildOverlayMain() {
|
||||
let isMinimized = false;
|
||||
overlayMain.addDiv({ "id": "bm-overlay", "style": "top: 10px; right: 75px;" }).addDiv({ "id": "bm-contain-header" }).addDiv({ "id": "bm-bar-drag" }).buildElement().addImg(
|
||||
{ "alt": "Blue Marble Icon - Click to minimize/maximize", "src": "https://raw.githubusercontent.com/SwingTheVine/Wplace-BlueMarble/main/dist/assets/Favicon.png", "style": "cursor: pointer;" },
|
||||
(instance, img) => {
|
||||
img.addEventListener("click", () => {
|
||||
isMinimized = !isMinimized;
|
||||
const overlay = document.querySelector("#bm-overlay");
|
||||
const header = document.querySelector("#bm-contain-header");
|
||||
const dragBar = document.querySelector("#bm-bar-drag");
|
||||
const coordsContainer = document.querySelector("#bm-contain-coords");
|
||||
const coordsButton = document.querySelector("#bm-button-coords");
|
||||
const createButton = document.querySelector("#bm-button-create");
|
||||
const enableButton = document.querySelector("#bm-button-enable");
|
||||
const disableButton = document.querySelector("#bm-button-disable");
|
||||
const coordInputs = document.querySelectorAll("#bm-contain-coords input");
|
||||
if (!isMinimized) {
|
||||
overlay.style.width = "auto";
|
||||
overlay.style.maxWidth = "300px";
|
||||
overlay.style.minWidth = "200px";
|
||||
overlay.style.padding = "10px";
|
||||
}
|
||||
const elementsToToggle = [
|
||||
"#bm-overlay h1",
|
||||
// Main title "Blue Marble"
|
||||
"#bm-contain-userinfo",
|
||||
// User information section (username, droplets, level)
|
||||
"#bm-overlay hr",
|
||||
// Visual separator lines
|
||||
"#bm-contain-automation > *:not(#bm-contain-coords)",
|
||||
// Automation section excluding coordinates
|
||||
"#bm-input-file-template",
|
||||
// Template file upload interface
|
||||
"#bm-contain-buttons-action",
|
||||
// Action buttons container
|
||||
`#${instance.outputStatusId}`
|
||||
// Status log textarea for user feedback
|
||||
];
|
||||
elementsToToggle.forEach((selector) => {
|
||||
const elements = document.querySelectorAll(selector);
|
||||
elements.forEach((element) => {
|
||||
element.style.display = isMinimized ? "none" : "";
|
||||
});
|
||||
overlayMain.addDiv({ "class": "bm-window", "style": "top: 10px; right: 75px;" }).addDiv({ "class": "bm-dragbar" }).addDiv().addButton({ "class": "bm-button-circle", "textContent": "\u25BC" }, (instance, button) => {
|
||||
button.onclick = () => {
|
||||
const window2 = button.closest(".bm-window");
|
||||
const dragbar = button.closest(".bm-dragbar");
|
||||
const header = window2.querySelector("h1");
|
||||
const windowContent = window2.querySelector(".bm-window-content");
|
||||
if (button.textContent == "\u25BC") {
|
||||
const dragbarHeader1 = header.cloneNode(true);
|
||||
button.parentNode.appendChild(dragbarHeader1);
|
||||
windowContent.style.height = windowContent.scrollHeight + "px";
|
||||
window2.style.width = window2.scrollWidth + "px";
|
||||
windowContent.style.height = "0";
|
||||
windowContent.addEventListener("transitionend", function handler() {
|
||||
windowContent.style.display = "none";
|
||||
windowContent.removeEventListener("transitionend", handler);
|
||||
});
|
||||
} else {
|
||||
const dragbarHeader1 = dragbar.querySelector("h1");
|
||||
dragbarHeader1.remove();
|
||||
windowContent.style.display = "";
|
||||
windowContent.style.height = "0";
|
||||
window2.style.width = "";
|
||||
windowContent.style.height = windowContent.scrollHeight + "px";
|
||||
windowContent.addEventListener("transitionend", function handler() {
|
||||
windowContent.style.height = "";
|
||||
windowContent.removeEventListener("transitionend", handler);
|
||||
});
|
||||
if (isMinimized) {
|
||||
if (coordsContainer) {
|
||||
coordsContainer.style.display = "none";
|
||||
}
|
||||
if (coordsButton) {
|
||||
coordsButton.style.display = "none";
|
||||
}
|
||||
if (createButton) {
|
||||
createButton.style.display = "none";
|
||||
}
|
||||
if (enableButton) {
|
||||
enableButton.style.display = "none";
|
||||
}
|
||||
if (disableButton) {
|
||||
disableButton.style.display = "none";
|
||||
}
|
||||
coordInputs.forEach((input) => {
|
||||
input.style.display = "none";
|
||||
});
|
||||
overlay.style.width = "60px";
|
||||
overlay.style.height = "76px";
|
||||
overlay.style.maxWidth = "60px";
|
||||
overlay.style.minWidth = "60px";
|
||||
overlay.style.padding = "8px";
|
||||
img.style.marginLeft = "3px";
|
||||
header.style.textAlign = "center";
|
||||
header.style.margin = "0";
|
||||
header.style.marginBottom = "0";
|
||||
if (dragBar) {
|
||||
dragBar.style.display = "";
|
||||
dragBar.style.marginBottom = "0.25em";
|
||||
}
|
||||
} else {
|
||||
if (coordsContainer) {
|
||||
coordsContainer.style.display = "";
|
||||
coordsContainer.style.flexDirection = "";
|
||||
coordsContainer.style.justifyContent = "";
|
||||
coordsContainer.style.alignItems = "";
|
||||
coordsContainer.style.gap = "";
|
||||
coordsContainer.style.textAlign = "";
|
||||
coordsContainer.style.margin = "";
|
||||
}
|
||||
if (coordsButton) {
|
||||
coordsButton.style.display = "";
|
||||
}
|
||||
if (createButton) {
|
||||
createButton.style.display = "";
|
||||
createButton.style.marginTop = "";
|
||||
}
|
||||
if (enableButton) {
|
||||
enableButton.style.display = "";
|
||||
enableButton.style.marginTop = "";
|
||||
}
|
||||
if (disableButton) {
|
||||
disableButton.style.display = "";
|
||||
disableButton.style.marginTop = "";
|
||||
}
|
||||
coordInputs.forEach((input) => {
|
||||
input.style.display = "";
|
||||
});
|
||||
img.style.marginLeft = "";
|
||||
overlay.style.padding = "10px";
|
||||
header.style.textAlign = "";
|
||||
header.style.margin = "";
|
||||
header.style.marginBottom = "";
|
||||
if (dragBar) {
|
||||
dragBar.style.marginBottom = "0.5em";
|
||||
}
|
||||
overlay.style.width = "";
|
||||
overlay.style.height = "";
|
||||
}
|
||||
img.alt = isMinimized ? "Blue Marble Icon - Minimized (Click to maximize)" : "Blue Marble Icon - Maximized (Click to minimize)";
|
||||
});
|
||||
}
|
||||
).buildElement().addHeader(1, { "textContent": name }).buildElement().buildElement().addHr().buildElement().addDiv({ "id": "bm-contain-userinfo" }).addP({ "id": "bm-user-droplets", "textContent": "Droplets:" }).buildElement().addP({ "id": "bm-user-nextlevel", "textContent": "Next level in..." }).buildElement().buildElement().addHr().buildElement().addDiv({ "id": "bm-contain-automation" }).addDiv({ "id": "bm-contain-coords" }).addButton(
|
||||
{ "id": "bm-button-coords", "className": "bm-help", "style": "margin-top: 0;", "innerHTML": '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 4 6"><circle cx="2" cy="2" r="2"></circle><path d="M2 6 L3.7 3 L0.3 3 Z"></path><circle cx="2" cy="2" r="0.7" fill="white"></circle></svg></svg>' },
|
||||
(instance, button) => {
|
||||
button.onclick = () => {
|
||||
const coords2 = instance.apiManager?.coordsTilePixel;
|
||||
if (!coords2?.[0]) {
|
||||
instance.handleDisplayError("Coordinates are malformed! Did you try clicking on the canvas first?");
|
||||
return;
|
||||
}
|
||||
instance.updateInnerHTML("bm-input-tx", coords2?.[0] || "");
|
||||
instance.updateInnerHTML("bm-input-ty", coords2?.[1] || "");
|
||||
instance.updateInnerHTML("bm-input-px", coords2?.[2] || "");
|
||||
instance.updateInnerHTML("bm-input-py", coords2?.[3] || "");
|
||||
};
|
||||
}
|
||||
).buildElement().addInput({ "type": "number", "id": "bm-input-tx", "placeholder": "Tl X", "min": 0, "max": 2047, "step": 1, "required": true }, (instance, input) => {
|
||||
input.addEventListener("paste", (event) => {
|
||||
let splitText = (event.clipboardData || window.clipboardData).getData("text").split(" ").filter((n) => n).map(Number).filter((n) => !isNaN(n));
|
||||
if (splitText.length !== 4) {
|
||||
return;
|
||||
}
|
||||
let coords2 = selectAllCoordinateInputs(document);
|
||||
for (let i = 0; i < coords2.length; i++) {
|
||||
coords2[i].value = splitText[i];
|
||||
}
|
||||
event.preventDefault();
|
||||
});
|
||||
const handler = () => persistCoords();
|
||||
input.addEventListener("input", handler);
|
||||
input.addEventListener("change", handler);
|
||||
}).buildElement().addInput({ "type": "number", "id": "bm-input-ty", "placeholder": "Tl Y", "min": 0, "max": 2047, "step": 1, "required": true }, (instance, input) => {
|
||||
const handler = () => persistCoords();
|
||||
input.addEventListener("input", handler);
|
||||
input.addEventListener("change", handler);
|
||||
}).buildElement().addInput({ "type": "number", "id": "bm-input-px", "placeholder": "Px X", "min": 0, "max": 2047, "step": 1, "required": true }, (instance, input) => {
|
||||
const handler = () => persistCoords();
|
||||
input.addEventListener("input", handler);
|
||||
input.addEventListener("change", handler);
|
||||
}).buildElement().addInput({ "type": "number", "id": "bm-input-py", "placeholder": "Px Y", "min": 0, "max": 2047, "step": 1, "required": true }, (instance, input) => {
|
||||
const handler = () => persistCoords();
|
||||
input.addEventListener("input", handler);
|
||||
input.addEventListener("change", handler);
|
||||
}).buildElement().buildElement().addInputFile({ "id": "bm-input-file-template", "textContent": "Upload Template", "accept": "image/png, image/jpeg, image/webp, image/bmp, image/gif" }).buildElement().addDiv({ "id": "bm-contain-buttons-template" }).addButton({ "id": "bm-button-enable", "textContent": "Enable" }, (instance, button) => {
|
||||
button.onclick = () => {
|
||||
instance.apiManager?.templateManager?.setTemplatesShouldBeDrawn(true);
|
||||
instance.handleDisplayStatus(`Enabled templates!`);
|
||||
button.textContent = button.textContent == "\u25BC" ? "\u25B6" : "\u25BC";
|
||||
};
|
||||
}).buildElement().addButton({ "id": "bm-button-create", "textContent": "Create" }, (instance, button) => {
|
||||
button.onclick = () => {
|
||||
const input = document.querySelector("#bm-input-file-template");
|
||||
const coordTlX = document.querySelector("#bm-input-tx");
|
||||
if (!coordTlX.checkValidity()) {
|
||||
coordTlX.reportValidity();
|
||||
instance.handleDisplayError("Coordinates are malformed! Did you try clicking on the canvas first?");
|
||||
return;
|
||||
}
|
||||
const coordTlY = document.querySelector("#bm-input-ty");
|
||||
if (!coordTlY.checkValidity()) {
|
||||
coordTlY.reportValidity();
|
||||
instance.handleDisplayError("Coordinates are malformed! Did you try clicking on the canvas first?");
|
||||
return;
|
||||
}
|
||||
const coordPxX = document.querySelector("#bm-input-px");
|
||||
if (!coordPxX.checkValidity()) {
|
||||
coordPxX.reportValidity();
|
||||
instance.handleDisplayError("Coordinates are malformed! Did you try clicking on the canvas first?");
|
||||
return;
|
||||
}
|
||||
const coordPxY = document.querySelector("#bm-input-py");
|
||||
if (!coordPxY.checkValidity()) {
|
||||
coordPxY.reportValidity();
|
||||
instance.handleDisplayError("Coordinates are malformed! Did you try clicking on the canvas first?");
|
||||
return;
|
||||
}
|
||||
if (!input?.files[0]) {
|
||||
instance.handleDisplayError(`No file selected!`);
|
||||
return;
|
||||
}
|
||||
templateManager.createTemplate(input.files[0], input.files[0]?.name.replace(/\.[^/.]+$/, ""), [Number(coordTlX.value), Number(coordTlY.value), Number(coordPxX.value), Number(coordPxY.value)]);
|
||||
instance.handleDisplayStatus(`Drew to canvas!`);
|
||||
};
|
||||
}).buildElement().addButton({ "id": "bm-button-disable", "textContent": "Disable" }, (instance, button) => {
|
||||
button.onclick = () => {
|
||||
instance.apiManager?.templateManager?.setTemplatesShouldBeDrawn(false);
|
||||
instance.handleDisplayStatus(`Disabled templates!`);
|
||||
};
|
||||
}).buildElement().buildElement().addTextarea({ "id": overlayMain.outputStatusId, "placeholder": `Status: Sleeping...
|
||||
Version: ${version}`, "readOnly": true }).buildElement().addDiv({ "id": "bm-contain-buttons-action" }).addDiv().addButton(
|
||||
{ "id": "bm-button-convert", "className": "bm-help", "innerHTML": "\u{1F3A8}", "title": "Template Color Converter" },
|
||||
(instance, button) => {
|
||||
button.addEventListener("click", () => {
|
||||
window.open("https://pepoafonso.github.io/color_converter_wplace/", "_blank", "noopener noreferrer");
|
||||
});
|
||||
}
|
||||
).buildElement().addButton(
|
||||
{ "id": "bm-button-website", "className": "bm-help", "innerHTML": "\u{1F310}", "title": "Official Blue Marble Website" },
|
||||
(instance, button) => {
|
||||
button.addEventListener("click", () => {
|
||||
window.open("https://bluemarble.lol/", "_blank", "noopener noreferrer");
|
||||
});
|
||||
}
|
||||
).buildElement().buildElement().addSmall({ "textContent": "Made by SwingTheVine", "style": "margin-top: auto;" }).buildElement().buildElement().buildElement().buildOverlay(document.body);
|
||||
}).buildElement().buildElement().buildElement().addDiv({ "class": "bm-window-content" }).addDiv({ "class": "bm-container" }).addImg({ "class": "bm-favicon", "src": "https://raw.githubusercontent.com/SwingTheVine/Wplace-BlueMarble/main/dist/assets/Favicon.png" }).buildElement().addHeader(1, { "textContent": name }).buildElement().buildElement().addHr().buildElement().buildElement().buildOverlay(document.body);
|
||||
}
|
||||
function buildTelemetryOverlay(overlay) {
|
||||
overlay.addDiv({ "id": "bm-overlay-telemetry", style: "top: 0px; left: 0px; width: 100vw; max-width: 100vw; height: 100vh; max-height: 100vh; z-index: 9999;" }).addDiv({ "id": "bm-contain-all-telemetry", style: "display: flex; flex-direction: column; align-items: center;" }).addDiv({ "id": "bm-contain-header-telemetry", style: "margin-top: 10%;" }).addHeader(1, { "textContent": `${name} Telemetry` }).buildElement().buildElement().addDiv({ "id": "bm-contain-telemetry", style: "max-width: 50%; overflow-y: auto; max-height: 80vh;" }).addHr().buildElement().addBr().buildElement().addDiv({ "style": "width: fit-content; margin: auto; text-align: center;" }).addButton({ "id": "bm-button-telemetry-more", "textContent": "More Information" }, (instance, button) => {
|
||||
|
|
|
|||
4
dist/BlueMarble-Standalone.user.js
vendored
4
dist/BlueMarble-Standalone.user.js
vendored
File diff suppressed because one or more lines are too long
2
dist/BlueMarble.user.css
vendored
2
dist/BlueMarble.user.css
vendored
File diff suppressed because one or more lines are too long
4
dist/BlueMarble.user.js
vendored
4
dist/BlueMarble.user.js
vendored
File diff suppressed because one or more lines are too long
|
|
@ -51,7 +51,7 @@
|
|||
<a href="https://discord.gg/tpeBPy46hf" target="_blank" rel="noopener noreferrer"><img alt="Contact Me" src="https://img.shields.io/badge/Contact_Me-gray?style=flat&logo=Discord&logoColor=white&logoSize=auto&labelColor=cornflowerblue"></a>
|
||||
<a href="https://bluemarble.lol/" target="_blank" rel="noopener noreferrer"><img alt="Blue Marble Website" src="https://img.shields.io/badge/Blue_Marble_Website-crqch-blue?style=flat&logo=globe&logoColor=white"></a>
|
||||
<a href="" target="_blank" rel="noopener noreferrer"><img alt="WakaTime" src="https://img.shields.io/badge/Coding_Time-111hrs_12mins-blue?style=flat&logo=wakatime&logoColor=black&logoSize=auto&labelColor=white"></a>
|
||||
<a href="" target="_blank" rel="noopener noreferrer"><img alt="Total Patches" src="https://img.shields.io/badge/Total_Patches-593-black?style=flat"></a>
|
||||
<a href="" target="_blank" rel="noopener noreferrer"><img alt="Total Patches" src="https://img.shields.io/badge/Total_Patches-620-black?style=flat"></a>
|
||||
<a href="" target="_blank" rel="noopener noreferrer"><img alt="Total Lines of Code" src="https://img.shields.io/badge/Lines_Of_Code-498-blue?style=flat"></a>
|
||||
<a href="" target="_blank" rel="noopener noreferrer"><img alt="Total Comments" src="https://img.shields.io/badge/Lines_Of_Comments-498-blue?style=flat"></a>
|
||||
<a href="" target="_blank" rel="noopener noreferrer"><img alt="Compression" src="https://img.shields.io/badge/Compression-70.19%25-blue"></a>
|
||||
|
|
|
|||
4
package-lock.json
generated
4
package-lock.json
generated
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "wplace-bluemarble",
|
||||
"version": "0.88.95",
|
||||
"version": "0.88.122",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "wplace-bluemarble",
|
||||
"version": "0.88.95",
|
||||
"version": "0.88.122",
|
||||
"devDependencies": {
|
||||
"esbuild": "^0.25.0",
|
||||
"jsdoc": "^4.0.5",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "wplace-bluemarble",
|
||||
"version": "0.88.95",
|
||||
"version": "0.88.122",
|
||||
"type": "module",
|
||||
"homepage": "https://bluemarble.lol/",
|
||||
"repository": {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
// @name Blue Marble
|
||||
// @name:en Blue Marble
|
||||
// @namespace https://github.com/SwingTheVine/
|
||||
// @version 0.88.95
|
||||
// @version 0.88.122
|
||||
// @description A userscript to automate and/or enhance the user experience on Wplace.live. Make sure to comply with the site's Terms of Service, and rules! This script is not affiliated with Wplace.live in any way, use at your own risk. This script is not affiliated with TamperMonkey. The author of this userscript is not responsible for any damages, issues, loss of data, or punishment that may occur as a result of using this script. This script is provided "as is" under the MPL-2.0 license. The "Blue Marble" icon is licensed under CC0 1.0 Universal (CC0 1.0) Public Domain Dedication. The image is owned by NASA.
|
||||
// @description:en A userscript to automate and/or enhance the user experience on Wplace.live. Make sure to comply with the site's Terms of Service, and rules! This script is not affiliated with Wplace.live in any way, use at your own risk. This script is not affiliated with TamperMonkey. The author of this userscript is not responsible for any damages, issues, loss of data, or punishment that may occur as a result of using this script. This script is provided "as is" under the MPL-2.0 license. The "Blue Marble" icon is licensed under CC0 1.0 Universal (CC0 1.0) Public Domain Dedication. The image is owned by NASA.
|
||||
// @author SwingTheVine
|
||||
|
|
|
|||
|
|
@ -73,12 +73,12 @@ export default class Overlay {
|
|||
|
||||
// For every passed in property (shared by all like-elements), apply the it to the element
|
||||
for (const [property, value] of Object.entries(properties)) {
|
||||
element[property] = value;
|
||||
element[(property != 'class') ? property : 'className'] = value; // if the property is 'class', pass in 'className' instead
|
||||
}
|
||||
|
||||
// For every passed in additional property, apply the it to the element
|
||||
for (const [property, value] of Object.entries(additionalProperties)) {
|
||||
element[property] = value;
|
||||
element[(property != 'class') ? property : 'className'] = value; // if the property is 'class', pass in 'className' instead
|
||||
}
|
||||
|
||||
return element;
|
||||
|
|
|
|||
636
src/main.js
636
src/main.js
|
|
@ -274,343 +274,389 @@ function observeBlack() {
|
|||
*/
|
||||
function buildOverlayMain() {
|
||||
|
||||
let isMinimized = false; // Overlay state tracker (false = maximized, true = minimized)
|
||||
overlayMain.addDiv({'class': 'bm-window', 'style': 'top: 10px; right: 75px;'})
|
||||
.addDiv({'class': 'bm-dragbar'})
|
||||
.addDiv()
|
||||
.addButton({'class': 'bm-button-circle', 'textContent': '▼'}, (instance, button) => {
|
||||
button.onclick = () => {
|
||||
const window = button.closest('.bm-window'); // Get the window
|
||||
const dragbar = button.closest('.bm-dragbar'); // Get the dragbar
|
||||
const header = window.querySelector('h1'); // Get the header
|
||||
const windowContent = window.querySelector('.bm-window-content'); // Get the window content container
|
||||
if (button.textContent == '▼') { // If window content is open...
|
||||
const dragbarHeader1 = header.cloneNode(true); // Makes a copy of the header 1
|
||||
button.parentNode.appendChild(dragbarHeader1); // Adds the header to the dragbar
|
||||
windowContent.style.height = windowContent.scrollHeight + 'px';
|
||||
window.style.width = window.scrollWidth + 'px'; // So the width of the window does not change due to the lack of content
|
||||
windowContent.style.height = '0'; // Set the height to 0px
|
||||
windowContent.addEventListener('transitionend', function handler() { // Add an event listener to cleanup once the minimize transition is complete
|
||||
windowContent.style.display = 'none'; // Changes "display" to "none" for screen readers
|
||||
windowContent.removeEventListener('transitionend', handler); // Removes the event listener
|
||||
});
|
||||
} else { // Else, the window is closed
|
||||
const dragbarHeader1 = dragbar.querySelector('h1'); // Get the header 1
|
||||
dragbarHeader1.remove(); // Removes the dragbar header 1
|
||||
windowContent.style.display = ''; // Resets display to default
|
||||
windowContent.style.height = '0'; // Sets the height to 0
|
||||
window.style.width = ''; // Resets the window width to default
|
||||
windowContent.style.height = windowContent.scrollHeight + 'px'; // Change the height back to normal
|
||||
windowContent.addEventListener('transitionend', function handler() { // Add an event listener to cleanup once the minimize transition is complete
|
||||
windowContent.style.height = ''; // Changes the height back to default
|
||||
windowContent.removeEventListener('transitionend', handler); // Removes the event listener
|
||||
});
|
||||
}
|
||||
button.textContent = (button.textContent == '▼') ? '▶' : '▼'; // Swap button icon
|
||||
}
|
||||
}).buildElement()
|
||||
.buildElement()
|
||||
.buildElement()
|
||||
.addDiv({'class': 'bm-window-content'})
|
||||
.addDiv({'class': 'bm-container'})
|
||||
.addImg({'class': 'bm-favicon', 'src': 'https://raw.githubusercontent.com/SwingTheVine/Wplace-BlueMarble/main/dist/assets/Favicon.png'}).buildElement()
|
||||
.addHeader(1, {'textContent': name}).buildElement()
|
||||
.buildElement()
|
||||
.addHr()
|
||||
.buildElement()
|
||||
.buildElement().buildOverlay(document.body);
|
||||
|
||||
|
||||
// let isMinimized = false; // Overlay state tracker (false = maximized, true = minimized)
|
||||
|
||||
overlayMain.addDiv({'id': 'bm-overlay', 'style': 'top: 10px; right: 75px;'})
|
||||
.addDiv({'id': 'bm-contain-header'})
|
||||
.addDiv({'id': 'bm-bar-drag'}).buildElement()
|
||||
.addImg({'alt': 'Blue Marble Icon - Click to minimize/maximize', 'src': 'https://raw.githubusercontent.com/SwingTheVine/Wplace-BlueMarble/main/dist/assets/Favicon.png', 'style': 'cursor: pointer;'},
|
||||
(instance, img) => {
|
||||
/** Click event handler for overlay minimize/maximize functionality.
|
||||
*
|
||||
* Toggles between two distinct UI states:
|
||||
* 1. MINIMIZED STATE (60×76px):
|
||||
* - Shows only the Blue Marble icon and drag bar
|
||||
* - Hides all input fields, buttons, and status information
|
||||
* - Applies fixed dimensions for consistent appearance
|
||||
* - Repositions icon with 3px right offset for visual centering
|
||||
*
|
||||
* 2. MAXIMIZED STATE (responsive):
|
||||
* - Restores full functionality with all UI elements
|
||||
* - Removes fixed dimensions to allow responsive behavior
|
||||
* - Resets icon positioning to default alignment
|
||||
* - Shows success message when returning to maximized state
|
||||
*
|
||||
* @param {Event} event - The click event object (implicit)
|
||||
*/
|
||||
img.addEventListener('click', () => {
|
||||
isMinimized = !isMinimized; // Toggle the current state
|
||||
// overlayMain.addDiv({'id': 'bm-overlay', 'style': 'top: 10px; right: 75px;'})
|
||||
// .addDiv({'id': 'bm-contain-header'})
|
||||
// .addDiv({'id': 'bm-bar-drag'}).buildElement()
|
||||
// .addImg({'alt': 'Blue Marble Icon - Click to minimize/maximize', 'src': 'https://raw.githubusercontent.com/SwingTheVine/Wplace-BlueMarble/main/dist/assets/Favicon.png', 'style': 'cursor: pointer;'},
|
||||
// (instance, img) => {
|
||||
// /** Click event handler for overlay minimize/maximize functionality.
|
||||
// *
|
||||
// * Toggles between two distinct UI states:
|
||||
// * 1. MINIMIZED STATE (60×76px):
|
||||
// * - Shows only the Blue Marble icon and drag bar
|
||||
// * - Hides all input fields, buttons, and status information
|
||||
// * - Applies fixed dimensions for consistent appearance
|
||||
// * - Repositions icon with 3px right offset for visual centering
|
||||
// *
|
||||
// * 2. MAXIMIZED STATE (responsive):
|
||||
// * - Restores full functionality with all UI elements
|
||||
// * - Removes fixed dimensions to allow responsive behavior
|
||||
// * - Resets icon positioning to default alignment
|
||||
// * - Shows success message when returning to maximized state
|
||||
// *
|
||||
// * @param {Event} event - The click event object (implicit)
|
||||
// */
|
||||
// img.addEventListener('click', () => {
|
||||
// isMinimized = !isMinimized; // Toggle the current state
|
||||
|
||||
const overlay = document.querySelector('#bm-overlay');
|
||||
const header = document.querySelector('#bm-contain-header');
|
||||
const dragBar = document.querySelector('#bm-bar-drag');
|
||||
const coordsContainer = document.querySelector('#bm-contain-coords');
|
||||
const coordsButton = document.querySelector('#bm-button-coords');
|
||||
const createButton = document.querySelector('#bm-button-create');
|
||||
const enableButton = document.querySelector('#bm-button-enable');
|
||||
const disableButton = document.querySelector('#bm-button-disable');
|
||||
const coordInputs = document.querySelectorAll('#bm-contain-coords input');
|
||||
// const overlay = document.querySelector('#bm-overlay');
|
||||
// const header = document.querySelector('#bm-contain-header');
|
||||
// const dragBar = document.querySelector('#bm-bar-drag');
|
||||
// const coordsContainer = document.querySelector('#bm-contain-coords');
|
||||
// const coordsButton = document.querySelector('#bm-button-coords');
|
||||
// const createButton = document.querySelector('#bm-button-create');
|
||||
// const enableButton = document.querySelector('#bm-button-enable');
|
||||
// const disableButton = document.querySelector('#bm-button-disable');
|
||||
// const coordInputs = document.querySelectorAll('#bm-contain-coords input');
|
||||
|
||||
// Pre-restore original dimensions when switching to maximized state
|
||||
// This ensures smooth transition and prevents layout issues
|
||||
if (!isMinimized) {
|
||||
overlay.style.width = "auto";
|
||||
overlay.style.maxWidth = "300px";
|
||||
overlay.style.minWidth = "200px";
|
||||
overlay.style.padding = "10px";
|
||||
}
|
||||
// // Pre-restore original dimensions when switching to maximized state
|
||||
// // This ensures smooth transition and prevents layout issues
|
||||
// if (!isMinimized) {
|
||||
// overlay.style.width = "auto";
|
||||
// overlay.style.maxWidth = "300px";
|
||||
// overlay.style.minWidth = "200px";
|
||||
// overlay.style.padding = "10px";
|
||||
// }
|
||||
|
||||
// Define elements that should be hidden/shown during state transitions
|
||||
// Each element is documented with its purpose for maintainability
|
||||
const elementsToToggle = [
|
||||
'#bm-overlay h1', // Main title "Blue Marble"
|
||||
'#bm-contain-userinfo', // User information section (username, droplets, level)
|
||||
'#bm-overlay hr', // Visual separator lines
|
||||
'#bm-contain-automation > *:not(#bm-contain-coords)', // Automation section excluding coordinates
|
||||
'#bm-input-file-template', // Template file upload interface
|
||||
'#bm-contain-buttons-action', // Action buttons container
|
||||
`#${instance.outputStatusId}`, // Status log textarea for user feedback
|
||||
];
|
||||
// // Define elements that should be hidden/shown during state transitions
|
||||
// // Each element is documented with its purpose for maintainability
|
||||
// const elementsToToggle = [
|
||||
// '#bm-overlay h1', // Main title "Blue Marble"
|
||||
// '#bm-contain-userinfo', // User information section (username, droplets, level)
|
||||
// '#bm-overlay hr', // Visual separator lines
|
||||
// '#bm-contain-automation > *:not(#bm-contain-coords)', // Automation section excluding coordinates
|
||||
// '#bm-input-file-template', // Template file upload interface
|
||||
// '#bm-contain-buttons-action', // Action buttons container
|
||||
// `#${instance.outputStatusId}`, // Status log textarea for user feedback
|
||||
// ];
|
||||
|
||||
// Apply visibility changes to all toggleable elements
|
||||
elementsToToggle.forEach(selector => {
|
||||
const elements = document.querySelectorAll(selector);
|
||||
elements.forEach(element => {
|
||||
element.style.display = isMinimized ? 'none' : '';
|
||||
});
|
||||
});
|
||||
// Handle coordinate container and button visibility based on state
|
||||
if (isMinimized) {
|
||||
// ==================== MINIMIZED STATE CONFIGURATION ====================
|
||||
// In minimized state, we hide ALL interactive elements except the icon and drag bar
|
||||
// This creates a clean, unobtrusive interface that maintains only essential functionality
|
||||
// // Apply visibility changes to all toggleable elements
|
||||
// elementsToToggle.forEach(selector => {
|
||||
// const elements = document.querySelectorAll(selector);
|
||||
// elements.forEach(element => {
|
||||
// element.style.display = isMinimized ? 'none' : '';
|
||||
// });
|
||||
// });
|
||||
// // Handle coordinate container and button visibility based on state
|
||||
// if (isMinimized) {
|
||||
// // ==================== MINIMIZED STATE CONFIGURATION ====================
|
||||
// // In minimized state, we hide ALL interactive elements except the icon and drag bar
|
||||
// // This creates a clean, unobtrusive interface that maintains only essential functionality
|
||||
|
||||
// Hide coordinate input container completely
|
||||
if (coordsContainer) {
|
||||
coordsContainer.style.display = 'none';
|
||||
}
|
||||
// // Hide coordinate input container completely
|
||||
// if (coordsContainer) {
|
||||
// coordsContainer.style.display = 'none';
|
||||
// }
|
||||
|
||||
// Hide coordinate button (pin icon)
|
||||
if (coordsButton) {
|
||||
coordsButton.style.display = 'none';
|
||||
}
|
||||
// // Hide coordinate button (pin icon)
|
||||
// if (coordsButton) {
|
||||
// coordsButton.style.display = 'none';
|
||||
// }
|
||||
|
||||
// Hide create template button
|
||||
if (createButton) {
|
||||
createButton.style.display = 'none';
|
||||
}
|
||||
// // Hide create template button
|
||||
// if (createButton) {
|
||||
// createButton.style.display = 'none';
|
||||
// }
|
||||
|
||||
// Hide enable templates button
|
||||
if (enableButton) {
|
||||
enableButton.style.display = 'none';
|
||||
}
|
||||
// // Hide enable templates button
|
||||
// if (enableButton) {
|
||||
// enableButton.style.display = 'none';
|
||||
// }
|
||||
|
||||
// Hide disable templates button
|
||||
if (disableButton) {
|
||||
disableButton.style.display = 'none';
|
||||
}
|
||||
// // Hide disable templates button
|
||||
// if (disableButton) {
|
||||
// disableButton.style.display = 'none';
|
||||
// }
|
||||
|
||||
// Hide all coordinate input fields individually (failsafe)
|
||||
coordInputs.forEach(input => {
|
||||
input.style.display = 'none';
|
||||
});
|
||||
// // Hide all coordinate input fields individually (failsafe)
|
||||
// coordInputs.forEach(input => {
|
||||
// input.style.display = 'none';
|
||||
// });
|
||||
|
||||
// Apply fixed dimensions for consistent minimized appearance
|
||||
// These dimensions were chosen to accommodate the icon while remaining compact
|
||||
overlay.style.width = '60px'; // Fixed width for consistency
|
||||
overlay.style.height = '76px'; // Fixed height (60px + 16px for better proportions)
|
||||
overlay.style.maxWidth = '60px'; // Prevent expansion
|
||||
overlay.style.minWidth = '60px'; // Prevent shrinking
|
||||
overlay.style.padding = '8px'; // Comfortable padding around icon
|
||||
// // Apply fixed dimensions for consistent minimized appearance
|
||||
// // These dimensions were chosen to accommodate the icon while remaining compact
|
||||
// overlay.style.width = '60px'; // Fixed width for consistency
|
||||
// overlay.style.height = '76px'; // Fixed height (60px + 16px for better proportions)
|
||||
// overlay.style.maxWidth = '60px'; // Prevent expansion
|
||||
// overlay.style.minWidth = '60px'; // Prevent shrinking
|
||||
// overlay.style.padding = '8px'; // Comfortable padding around icon
|
||||
|
||||
// Apply icon positioning for better visual centering in minimized state
|
||||
// The 3px offset compensates for visual weight distribution
|
||||
img.style.marginLeft = '3px';
|
||||
// // Apply icon positioning for better visual centering in minimized state
|
||||
// // The 3px offset compensates for visual weight distribution
|
||||
// img.style.marginLeft = '3px';
|
||||
|
||||
// Configure header layout for minimized state
|
||||
header.style.textAlign = 'center';
|
||||
header.style.margin = '0';
|
||||
header.style.marginBottom = '0';
|
||||
// // Configure header layout for minimized state
|
||||
// header.style.textAlign = 'center';
|
||||
// header.style.margin = '0';
|
||||
// header.style.marginBottom = '0';
|
||||
|
||||
// Ensure drag bar remains visible and properly spaced
|
||||
if (dragBar) {
|
||||
dragBar.style.display = '';
|
||||
dragBar.style.marginBottom = '0.25em';
|
||||
}
|
||||
} else {
|
||||
// ==================== MAXIMIZED STATE RESTORATION ====================
|
||||
// In maximized state, we restore all elements to their default functionality
|
||||
// This involves clearing all style overrides applied during minimization
|
||||
// // Ensure drag bar remains visible and properly spaced
|
||||
// if (dragBar) {
|
||||
// dragBar.style.display = '';
|
||||
// dragBar.style.marginBottom = '0.25em';
|
||||
// }
|
||||
// } else {
|
||||
// // ==================== MAXIMIZED STATE RESTORATION ====================
|
||||
// // In maximized state, we restore all elements to their default functionality
|
||||
// // This involves clearing all style overrides applied during minimization
|
||||
|
||||
// Restore coordinate container to default state
|
||||
if (coordsContainer) {
|
||||
coordsContainer.style.display = ''; // Show container
|
||||
coordsContainer.style.flexDirection = ''; // Reset flex layout
|
||||
coordsContainer.style.justifyContent = ''; // Reset alignment
|
||||
coordsContainer.style.alignItems = ''; // Reset alignment
|
||||
coordsContainer.style.gap = ''; // Reset spacing
|
||||
coordsContainer.style.textAlign = ''; // Reset text alignment
|
||||
coordsContainer.style.margin = ''; // Reset margins
|
||||
}
|
||||
// // Restore coordinate container to default state
|
||||
// if (coordsContainer) {
|
||||
// coordsContainer.style.display = ''; // Show container
|
||||
// coordsContainer.style.flexDirection = ''; // Reset flex layout
|
||||
// coordsContainer.style.justifyContent = ''; // Reset alignment
|
||||
// coordsContainer.style.alignItems = ''; // Reset alignment
|
||||
// coordsContainer.style.gap = ''; // Reset spacing
|
||||
// coordsContainer.style.textAlign = ''; // Reset text alignment
|
||||
// coordsContainer.style.margin = ''; // Reset margins
|
||||
// }
|
||||
|
||||
// Restore coordinate button visibility
|
||||
if (coordsButton) {
|
||||
coordsButton.style.display = '';
|
||||
}
|
||||
// // Restore coordinate button visibility
|
||||
// if (coordsButton) {
|
||||
// coordsButton.style.display = '';
|
||||
// }
|
||||
|
||||
// Restore create button visibility and reset positioning
|
||||
if (createButton) {
|
||||
createButton.style.display = '';
|
||||
createButton.style.marginTop = '';
|
||||
}
|
||||
// // Restore create button visibility and reset positioning
|
||||
// if (createButton) {
|
||||
// createButton.style.display = '';
|
||||
// createButton.style.marginTop = '';
|
||||
// }
|
||||
|
||||
// Restore enable button visibility and reset positioning
|
||||
if (enableButton) {
|
||||
enableButton.style.display = '';
|
||||
enableButton.style.marginTop = '';
|
||||
}
|
||||
// // Restore enable button visibility and reset positioning
|
||||
// if (enableButton) {
|
||||
// enableButton.style.display = '';
|
||||
// enableButton.style.marginTop = '';
|
||||
// }
|
||||
|
||||
// Restore disable button visibility and reset positioning
|
||||
if (disableButton) {
|
||||
disableButton.style.display = '';
|
||||
disableButton.style.marginTop = '';
|
||||
}
|
||||
// // Restore disable button visibility and reset positioning
|
||||
// if (disableButton) {
|
||||
// disableButton.style.display = '';
|
||||
// disableButton.style.marginTop = '';
|
||||
// }
|
||||
|
||||
// Restore all coordinate input fields
|
||||
coordInputs.forEach(input => {
|
||||
input.style.display = '';
|
||||
});
|
||||
// // Restore all coordinate input fields
|
||||
// coordInputs.forEach(input => {
|
||||
// input.style.display = '';
|
||||
// });
|
||||
|
||||
// Reset icon positioning to default (remove minimized state offset)
|
||||
img.style.marginLeft = '';
|
||||
// // Reset icon positioning to default (remove minimized state offset)
|
||||
// img.style.marginLeft = '';
|
||||
|
||||
// Restore overlay to responsive dimensions
|
||||
overlay.style.padding = '10px';
|
||||
// // Restore overlay to responsive dimensions
|
||||
// overlay.style.padding = '10px';
|
||||
|
||||
// Reset header styling to defaults
|
||||
header.style.textAlign = '';
|
||||
header.style.margin = '';
|
||||
header.style.marginBottom = '';
|
||||
// // Reset header styling to defaults
|
||||
// header.style.textAlign = '';
|
||||
// header.style.margin = '';
|
||||
// header.style.marginBottom = '';
|
||||
|
||||
// Reset drag bar spacing
|
||||
if (dragBar) {
|
||||
dragBar.style.marginBottom = '0.5em';
|
||||
}
|
||||
// // Reset drag bar spacing
|
||||
// if (dragBar) {
|
||||
// dragBar.style.marginBottom = '0.5em';
|
||||
// }
|
||||
|
||||
// Remove all fixed dimensions to allow responsive behavior
|
||||
// This ensures the overlay can adapt to content changes
|
||||
overlay.style.width = '';
|
||||
overlay.style.height = '';
|
||||
}
|
||||
// // Remove all fixed dimensions to allow responsive behavior
|
||||
// // This ensures the overlay can adapt to content changes
|
||||
// overlay.style.width = '';
|
||||
// overlay.style.height = '';
|
||||
// }
|
||||
|
||||
// ==================== ACCESSIBILITY AND USER FEEDBACK ====================
|
||||
// Update accessibility information for screen readers and tooltips
|
||||
// // ==================== ACCESSIBILITY AND USER FEEDBACK ====================
|
||||
// // Update accessibility information for screen readers and tooltips
|
||||
|
||||
// Update alt text to reflect current state for screen readers and tooltips
|
||||
img.alt = isMinimized ?
|
||||
'Blue Marble Icon - Minimized (Click to maximize)' :
|
||||
'Blue Marble Icon - Maximized (Click to minimize)';
|
||||
// // Update alt text to reflect current state for screen readers and tooltips
|
||||
// img.alt = isMinimized ?
|
||||
// 'Blue Marble Icon - Minimized (Click to maximize)' :
|
||||
// 'Blue Marble Icon - Maximized (Click to minimize)';
|
||||
|
||||
// No status message needed - state change is visually obvious to users
|
||||
});
|
||||
}
|
||||
).buildElement()
|
||||
.addHeader(1, {'textContent': name}).buildElement()
|
||||
.buildElement()
|
||||
// // No status message needed - state change is visually obvious to users
|
||||
// });
|
||||
// }
|
||||
// ).buildElement()
|
||||
// .addHeader(1, {'textContent': name}).buildElement()
|
||||
// .buildElement()
|
||||
|
||||
.addHr().buildElement()
|
||||
// .addHr().buildElement()
|
||||
|
||||
.addDiv({'id': 'bm-contain-userinfo'})
|
||||
.addP({'id': 'bm-user-droplets', 'textContent': 'Droplets:'}).buildElement()
|
||||
.addP({'id': 'bm-user-nextlevel', 'textContent': 'Next level in...'}).buildElement()
|
||||
.buildElement()
|
||||
// .addDiv({'id': 'bm-contain-userinfo'})
|
||||
// .addP({'id': 'bm-user-droplets', 'textContent': 'Droplets:'}).buildElement()
|
||||
// .addP({'id': 'bm-user-nextlevel', 'textContent': 'Next level in...'}).buildElement()
|
||||
// .buildElement()
|
||||
|
||||
.addHr().buildElement()
|
||||
// .addHr().buildElement()
|
||||
|
||||
.addDiv({'id': 'bm-contain-automation'})
|
||||
// .addCheckbox({'id': 'bm-input-stealth', 'textContent': 'Stealth', 'checked': true}).buildElement()
|
||||
// .addButtonHelp({'title': 'Waits for the website to make requests, instead of sending requests.'}).buildElement()
|
||||
// .addBr().buildElement()
|
||||
// .addCheckbox({'id': 'bm-input-possessed', 'textContent': 'Possessed', 'checked': true}).buildElement()
|
||||
// .addButtonHelp({'title': 'Controls the website as if it were possessed.'}).buildElement()
|
||||
// .addBr().buildElement()
|
||||
.addDiv({'id': 'bm-contain-coords'})
|
||||
.addButton({'id': 'bm-button-coords', 'className': 'bm-help', 'style': 'margin-top: 0;', 'innerHTML': '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 4 6"><circle cx="2" cy="2" r="2"></circle><path d="M2 6 L3.7 3 L0.3 3 Z"></path><circle cx="2" cy="2" r="0.7" fill="white"></circle></svg></svg>'},
|
||||
(instance, button) => {
|
||||
button.onclick = () => {
|
||||
const coords = instance.apiManager?.coordsTilePixel; // Retrieves the coords from the API manager
|
||||
if (!coords?.[0]) {
|
||||
instance.handleDisplayError('Coordinates are malformed! Did you try clicking on the canvas first?');
|
||||
return;
|
||||
}
|
||||
instance.updateInnerHTML('bm-input-tx', coords?.[0] || '');
|
||||
instance.updateInnerHTML('bm-input-ty', coords?.[1] || '');
|
||||
instance.updateInnerHTML('bm-input-px', coords?.[2] || '');
|
||||
instance.updateInnerHTML('bm-input-py', coords?.[3] || '');
|
||||
}
|
||||
}
|
||||
).buildElement()
|
||||
.addInput({'type': 'number', 'id': 'bm-input-tx', 'placeholder': 'Tl X', 'min': 0, 'max': 2047, 'step': 1, 'required': true}, (instance, input) => {
|
||||
//if a paste happens on tx, split and format it into other coordinates if possible
|
||||
input.addEventListener("paste", (event) => {
|
||||
let splitText = (event.clipboardData || window.clipboardData).getData("text").split(" ").filter(n => n).map(Number).filter(n => !isNaN(n)); //split and filter all Non Numbers
|
||||
// .addDiv({'id': 'bm-contain-automation'})
|
||||
// // .addCheckbox({'id': 'bm-input-stealth', 'textContent': 'Stealth', 'checked': true}).buildElement()
|
||||
// // .addButtonHelp({'title': 'Waits for the website to make requests, instead of sending requests.'}).buildElement()
|
||||
// // .addBr().buildElement()
|
||||
// // .addCheckbox({'id': 'bm-input-possessed', 'textContent': 'Possessed', 'checked': true}).buildElement()
|
||||
// // .addButtonHelp({'title': 'Controls the website as if it were possessed.'}).buildElement()
|
||||
// // .addBr().buildElement()
|
||||
// .addDiv({'id': 'bm-contain-coords'})
|
||||
// .addButton({'id': 'bm-button-coords', 'className': 'bm-help', 'style': 'margin-top: 0;', 'innerHTML': '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 4 6"><circle cx="2" cy="2" r="2"></circle><path d="M2 6 L3.7 3 L0.3 3 Z"></path><circle cx="2" cy="2" r="0.7" fill="white"></circle></svg></svg>'},
|
||||
// (instance, button) => {
|
||||
// button.onclick = () => {
|
||||
// const coords = instance.apiManager?.coordsTilePixel; // Retrieves the coords from the API manager
|
||||
// if (!coords?.[0]) {
|
||||
// instance.handleDisplayError('Coordinates are malformed! Did you try clicking on the canvas first?');
|
||||
// return;
|
||||
// }
|
||||
// instance.updateInnerHTML('bm-input-tx', coords?.[0] || '');
|
||||
// instance.updateInnerHTML('bm-input-ty', coords?.[1] || '');
|
||||
// instance.updateInnerHTML('bm-input-px', coords?.[2] || '');
|
||||
// instance.updateInnerHTML('bm-input-py', coords?.[3] || '');
|
||||
// }
|
||||
// }
|
||||
// ).buildElement()
|
||||
// .addInput({'type': 'number', 'id': 'bm-input-tx', 'placeholder': 'Tl X', 'min': 0, 'max': 2047, 'step': 1, 'required': true}, (instance, input) => {
|
||||
// //if a paste happens on tx, split and format it into other coordinates if possible
|
||||
// input.addEventListener("paste", (event) => {
|
||||
// let splitText = (event.clipboardData || window.clipboardData).getData("text").split(" ").filter(n => n).map(Number).filter(n => !isNaN(n)); //split and filter all Non Numbers
|
||||
|
||||
if (splitText.length !== 4 ) { // If we don't have 4 clean coordinates, end the function.
|
||||
return;
|
||||
}
|
||||
// if (splitText.length !== 4 ) { // If we don't have 4 clean coordinates, end the function.
|
||||
// return;
|
||||
// }
|
||||
|
||||
let coords = selectAllCoordinateInputs(document);
|
||||
// let coords = selectAllCoordinateInputs(document);
|
||||
|
||||
for (let i = 0; i < coords.length; i++) {
|
||||
coords[i].value = splitText[i]; //add the split vales
|
||||
}
|
||||
// for (let i = 0; i < coords.length; i++) {
|
||||
// coords[i].value = splitText[i]; //add the split vales
|
||||
// }
|
||||
|
||||
event.preventDefault(); //prevent the pasting of the original paste that would overide the split value
|
||||
})
|
||||
const handler = () => persistCoords();
|
||||
input.addEventListener('input', handler);
|
||||
input.addEventListener('change', handler);
|
||||
}).buildElement()
|
||||
.addInput({'type': 'number', 'id': 'bm-input-ty', 'placeholder': 'Tl Y', 'min': 0, 'max': 2047, 'step': 1, 'required': true}, (instance, input) => {
|
||||
const handler = () => persistCoords();
|
||||
input.addEventListener('input', handler);
|
||||
input.addEventListener('change', handler);
|
||||
}).buildElement()
|
||||
.addInput({'type': 'number', 'id': 'bm-input-px', 'placeholder': 'Px X', 'min': 0, 'max': 2047, 'step': 1, 'required': true}, (instance, input) => {
|
||||
const handler = () => persistCoords();
|
||||
input.addEventListener('input', handler);
|
||||
input.addEventListener('change', handler);
|
||||
}).buildElement()
|
||||
.addInput({'type': 'number', 'id': 'bm-input-py', 'placeholder': 'Px Y', 'min': 0, 'max': 2047, 'step': 1, 'required': true}, (instance, input) => {
|
||||
const handler = () => persistCoords();
|
||||
input.addEventListener('input', handler);
|
||||
input.addEventListener('change', handler);
|
||||
}).buildElement()
|
||||
.buildElement()
|
||||
.addInputFile({'id': 'bm-input-file-template', 'textContent': 'Upload Template', 'accept': 'image/png, image/jpeg, image/webp, image/bmp, image/gif'}).buildElement()
|
||||
.addDiv({'id': 'bm-contain-buttons-template'})
|
||||
.addButton({'id': 'bm-button-enable', 'textContent': 'Enable'}, (instance, button) => {
|
||||
button.onclick = () => {
|
||||
instance.apiManager?.templateManager?.setTemplatesShouldBeDrawn(true);
|
||||
instance.handleDisplayStatus(`Enabled templates!`);
|
||||
}
|
||||
}).buildElement()
|
||||
.addButton({'id': 'bm-button-create', 'textContent': 'Create'}, (instance, button) => {
|
||||
button.onclick = () => {
|
||||
const input = document.querySelector('#bm-input-file-template');
|
||||
// event.preventDefault(); //prevent the pasting of the original paste that would overide the split value
|
||||
// })
|
||||
// const handler = () => persistCoords();
|
||||
// input.addEventListener('input', handler);
|
||||
// input.addEventListener('change', handler);
|
||||
// }).buildElement()
|
||||
// .addInput({'type': 'number', 'id': 'bm-input-ty', 'placeholder': 'Tl Y', 'min': 0, 'max': 2047, 'step': 1, 'required': true}, (instance, input) => {
|
||||
// const handler = () => persistCoords();
|
||||
// input.addEventListener('input', handler);
|
||||
// input.addEventListener('change', handler);
|
||||
// }).buildElement()
|
||||
// .addInput({'type': 'number', 'id': 'bm-input-px', 'placeholder': 'Px X', 'min': 0, 'max': 2047, 'step': 1, 'required': true}, (instance, input) => {
|
||||
// const handler = () => persistCoords();
|
||||
// input.addEventListener('input', handler);
|
||||
// input.addEventListener('change', handler);
|
||||
// }).buildElement()
|
||||
// .addInput({'type': 'number', 'id': 'bm-input-py', 'placeholder': 'Px Y', 'min': 0, 'max': 2047, 'step': 1, 'required': true}, (instance, input) => {
|
||||
// const handler = () => persistCoords();
|
||||
// input.addEventListener('input', handler);
|
||||
// input.addEventListener('change', handler);
|
||||
// }).buildElement()
|
||||
// .buildElement()
|
||||
// .addInputFile({'id': 'bm-input-file-template', 'textContent': 'Upload Template', 'accept': 'image/png, image/jpeg, image/webp, image/bmp, image/gif'}).buildElement()
|
||||
// .addDiv({'id': 'bm-contain-buttons-template'})
|
||||
// .addButton({'id': 'bm-button-enable', 'textContent': 'Enable'}, (instance, button) => {
|
||||
// button.onclick = () => {
|
||||
// instance.apiManager?.templateManager?.setTemplatesShouldBeDrawn(true);
|
||||
// instance.handleDisplayStatus(`Enabled templates!`);
|
||||
// }
|
||||
// }).buildElement()
|
||||
// .addButton({'id': 'bm-button-create', 'textContent': 'Create'}, (instance, button) => {
|
||||
// button.onclick = () => {
|
||||
// const input = document.querySelector('#bm-input-file-template');
|
||||
|
||||
const coordTlX = document.querySelector('#bm-input-tx');
|
||||
if (!coordTlX.checkValidity()) {coordTlX.reportValidity(); instance.handleDisplayError('Coordinates are malformed! Did you try clicking on the canvas first?'); return;}
|
||||
const coordTlY = document.querySelector('#bm-input-ty');
|
||||
if (!coordTlY.checkValidity()) {coordTlY.reportValidity(); instance.handleDisplayError('Coordinates are malformed! Did you try clicking on the canvas first?'); return;}
|
||||
const coordPxX = document.querySelector('#bm-input-px');
|
||||
if (!coordPxX.checkValidity()) {coordPxX.reportValidity(); instance.handleDisplayError('Coordinates are malformed! Did you try clicking on the canvas first?'); return;}
|
||||
const coordPxY = document.querySelector('#bm-input-py');
|
||||
if (!coordPxY.checkValidity()) {coordPxY.reportValidity(); instance.handleDisplayError('Coordinates are malformed! Did you try clicking on the canvas first?'); return;}
|
||||
// const coordTlX = document.querySelector('#bm-input-tx');
|
||||
// if (!coordTlX.checkValidity()) {coordTlX.reportValidity(); instance.handleDisplayError('Coordinates are malformed! Did you try clicking on the canvas first?'); return;}
|
||||
// const coordTlY = document.querySelector('#bm-input-ty');
|
||||
// if (!coordTlY.checkValidity()) {coordTlY.reportValidity(); instance.handleDisplayError('Coordinates are malformed! Did you try clicking on the canvas first?'); return;}
|
||||
// const coordPxX = document.querySelector('#bm-input-px');
|
||||
// if (!coordPxX.checkValidity()) {coordPxX.reportValidity(); instance.handleDisplayError('Coordinates are malformed! Did you try clicking on the canvas first?'); return;}
|
||||
// const coordPxY = document.querySelector('#bm-input-py');
|
||||
// if (!coordPxY.checkValidity()) {coordPxY.reportValidity(); instance.handleDisplayError('Coordinates are malformed! Did you try clicking on the canvas first?'); return;}
|
||||
|
||||
// Kills itself if there is no file
|
||||
if (!input?.files[0]) {instance.handleDisplayError(`No file selected!`); return;}
|
||||
// // Kills itself if there is no file
|
||||
// if (!input?.files[0]) {instance.handleDisplayError(`No file selected!`); return;}
|
||||
|
||||
templateManager.createTemplate(input.files[0], input.files[0]?.name.replace(/\.[^/.]+$/, ''), [Number(coordTlX.value), Number(coordTlY.value), Number(coordPxX.value), Number(coordPxY.value)]);
|
||||
// templateManager.createTemplate(input.files[0], input.files[0]?.name.replace(/\.[^/.]+$/, ''), [Number(coordTlX.value), Number(coordTlY.value), Number(coordPxX.value), Number(coordPxY.value)]);
|
||||
|
||||
// console.log(`TCoords: ${apiManager.templateCoordsTilePixel}\nCoords: ${apiManager.coordsTilePixel}`);
|
||||
// apiManager.templateCoordsTilePixel = apiManager.coordsTilePixel; // Update template coords
|
||||
// console.log(`TCoords: ${apiManager.templateCoordsTilePixel}\nCoords: ${apiManager.coordsTilePixel}`);
|
||||
// templateManager.setTemplateImage(input.files[0]);
|
||||
// // console.log(`TCoords: ${apiManager.templateCoordsTilePixel}\nCoords: ${apiManager.coordsTilePixel}`);
|
||||
// // apiManager.templateCoordsTilePixel = apiManager.coordsTilePixel; // Update template coords
|
||||
// // console.log(`TCoords: ${apiManager.templateCoordsTilePixel}\nCoords: ${apiManager.coordsTilePixel}`);
|
||||
// // templateManager.setTemplateImage(input.files[0]);
|
||||
|
||||
instance.handleDisplayStatus(`Drew to canvas!`);
|
||||
}
|
||||
}).buildElement()
|
||||
.addButton({'id': 'bm-button-disable', 'textContent': 'Disable'}, (instance, button) => {
|
||||
button.onclick = () => {
|
||||
instance.apiManager?.templateManager?.setTemplatesShouldBeDrawn(false);
|
||||
instance.handleDisplayStatus(`Disabled templates!`);
|
||||
}
|
||||
}).buildElement()
|
||||
.buildElement()
|
||||
.addTextarea({'id': overlayMain.outputStatusId, 'placeholder': `Status: Sleeping...\nVersion: ${version}`, 'readOnly': true}).buildElement()
|
||||
.addDiv({'id': 'bm-contain-buttons-action'})
|
||||
.addDiv()
|
||||
// .addButton({'id': 'bm-button-teleport', 'className': 'bm-help', 'textContent': '✈'}).buildElement()
|
||||
// .addButton({'id': 'bm-button-favorite', 'className': 'bm-help', 'innerHTML': '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><polygon points="10,2 12,7.5 18,7.5 13.5,11.5 15.5,18 10,14 4.5,18 6.5,11.5 2,7.5 8,7.5" fill="white"></polygon></svg>'}).buildElement()
|
||||
// .addButton({'id': 'bm-button-templates', 'className': 'bm-help', 'innerHTML': '🖌'}).buildElement()
|
||||
.addButton({'id': 'bm-button-convert', 'className': 'bm-help', 'innerHTML': '🎨', 'title': 'Template Color Converter'},
|
||||
(instance, button) => {
|
||||
button.addEventListener('click', () => {
|
||||
window.open('https://pepoafonso.github.io/color_converter_wplace/', '_blank', 'noopener noreferrer');
|
||||
});
|
||||
}).buildElement()
|
||||
.addButton({'id': 'bm-button-website', 'className': 'bm-help', 'innerHTML': '🌐', 'title': 'Official Blue Marble Website'},
|
||||
(instance, button) => {
|
||||
button.addEventListener('click', () => {
|
||||
window.open('https://bluemarble.lol/', '_blank', 'noopener noreferrer');
|
||||
});
|
||||
}).buildElement()
|
||||
.buildElement()
|
||||
.addSmall({'textContent': 'Made by SwingTheVine', 'style': 'margin-top: auto;'}).buildElement()
|
||||
.buildElement()
|
||||
.buildElement()
|
||||
.buildOverlay(document.body);
|
||||
// instance.handleDisplayStatus(`Drew to canvas!`);
|
||||
// }
|
||||
// }).buildElement()
|
||||
// .addButton({'id': 'bm-button-disable', 'textContent': 'Disable'}, (instance, button) => {
|
||||
// button.onclick = () => {
|
||||
// instance.apiManager?.templateManager?.setTemplatesShouldBeDrawn(false);
|
||||
// instance.handleDisplayStatus(`Disabled templates!`);
|
||||
// }
|
||||
// }).buildElement()
|
||||
// .buildElement()
|
||||
// .addTextarea({'id': overlayMain.outputStatusId, 'placeholder': `Status: Sleeping...\nVersion: ${version}`, 'readOnly': true}).buildElement()
|
||||
// .addDiv({'id': 'bm-contain-buttons-action'})
|
||||
// .addDiv()
|
||||
// // .addButton({'id': 'bm-button-teleport', 'className': 'bm-help', 'textContent': '✈'}).buildElement()
|
||||
// // .addButton({'id': 'bm-button-favorite', 'className': 'bm-help', 'innerHTML': '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><polygon points="10,2 12,7.5 18,7.5 13.5,11.5 15.5,18 10,14 4.5,18 6.5,11.5 2,7.5 8,7.5" fill="white"></polygon></svg>'}).buildElement()
|
||||
// // .addButton({'id': 'bm-button-templates', 'className': 'bm-help', 'innerHTML': '🖌'}).buildElement()
|
||||
// .addButton({'id': 'bm-button-convert', 'className': 'bm-help', 'innerHTML': '🎨', 'title': 'Template Color Converter'},
|
||||
// (instance, button) => {
|
||||
// button.addEventListener('click', () => {
|
||||
// window.open('https://pepoafonso.github.io/color_converter_wplace/', '_blank', 'noopener noreferrer');
|
||||
// });
|
||||
// }).buildElement()
|
||||
// .addButton({'id': 'bm-button-website', 'className': 'bm-help', 'innerHTML': '🌐', 'title': 'Official Blue Marble Website'},
|
||||
// (instance, button) => {
|
||||
// button.addEventListener('click', () => {
|
||||
// window.open('https://bluemarble.lol/', '_blank', 'noopener noreferrer');
|
||||
// });
|
||||
// }).buildElement()
|
||||
// .buildElement()
|
||||
// .addSmall({'textContent': 'Made by SwingTheVine', 'style': 'margin-top: auto;'}).buildElement()
|
||||
// .buildElement()
|
||||
// .buildElement()
|
||||
// .buildOverlay(document.body);
|
||||
}
|
||||
|
||||
function buildTelemetryOverlay(overlay) {
|
||||
|
|
|
|||
144
src/overlay.css
144
src/overlay.css
|
|
@ -1,5 +1,149 @@
|
|||
/* @since 0.5.1 */
|
||||
|
||||
|
||||
/* The Blue Marble window(s) */
|
||||
.bm-window {
|
||||
position: fixed;
|
||||
background-color: rgba(21, 48, 99, 0.9);
|
||||
color: white;
|
||||
padding: 10px;
|
||||
border-radius: 8px;
|
||||
z-index: 9000;
|
||||
transition: all 0.3s ease, transform 0s;
|
||||
max-width: 300px;
|
||||
width: auto;
|
||||
/* Font stack is as follows:
|
||||
* Highest Priority (Roboto Mono)
|
||||
* Windows fallback (Courier New)
|
||||
* macOS fallback (Monaco)
|
||||
* Linux fallback (DejaVu Sans Mono)
|
||||
* Any possible monospace font (monospace)
|
||||
* Last resort (Arial) */
|
||||
font-family: 'Roboto Mono', 'Courier New', 'Monaco', 'DejaVu Sans Mono', monospace, 'Arial';
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
/* The drag bar */
|
||||
.bm-dragbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: space-between;
|
||||
gap: 0.5ch;
|
||||
/* For background circles, width & height should be odd, cx & cy should be half of width & height, and r should be less than or equal to cx & cy */
|
||||
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="5" height="5"><circle cx="3" cy="3" r="1.5" fill="CornflowerBlue" /></svg>') repeat;
|
||||
cursor: grab;
|
||||
width: 100%;
|
||||
height: fit-content;
|
||||
}
|
||||
|
||||
/* When a window is being dragged */
|
||||
.bm-dragbar.bm-dragging {
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
/* Disable interactions during drag for better performance */
|
||||
.bm-window:has(.bm-dragbar.bm-dragging) {
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
}
|
||||
|
||||
/* Keep drag bar interactive when dragging */
|
||||
.bm-dragbar.bm-dragging {
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
/* The Blue Marble Favicon */
|
||||
.bm-favicon {
|
||||
display: inline-block;
|
||||
height: 2.5em;
|
||||
margin-right: 1ch;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
|
||||
/* Header 1 */
|
||||
.bm-window h1 {
|
||||
display: inline-block;
|
||||
font-size: x-large;
|
||||
font-weight: bold;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
/* Header 1 when inside dragbar */
|
||||
.bm-dragbar h1 {
|
||||
font-size: 1.2em;
|
||||
margin-left: 0.5ch;
|
||||
user-select: none;
|
||||
text-shadow:
|
||||
3px 0px rgba(21, 48, 99, 0.5),
|
||||
-3px 0px rgba(21, 48, 99, 0.5),
|
||||
0px 3px rgba(21, 48, 99, 0.5),
|
||||
0px -3px rgba(21, 48, 99, 0.5),
|
||||
3px 3px rgba(21, 48, 99, 0.5),
|
||||
-3px 3px rgba(21, 48, 99, 0.5),
|
||||
3px -3px rgba(21, 48, 99, 0.5),
|
||||
-3px -3px rgba(21, 48, 99, 0.5);
|
||||
}
|
||||
|
||||
/* Containers for "sections" of elements */
|
||||
.bm-container {
|
||||
margin: 0.5em 0;
|
||||
}
|
||||
|
||||
/* All window buttons */
|
||||
.bm-window button {
|
||||
background-color: #144eb9;
|
||||
border-radius: 1em;
|
||||
padding: 0 0.75ch;
|
||||
}
|
||||
|
||||
/* All window buttons when hovered/focused */
|
||||
.bm-window button:hover, .bm-window button:focus-visible {
|
||||
background-color: #1061e5;
|
||||
}
|
||||
|
||||
/* All window buttons when pressed (plus disabled color) */
|
||||
.bm-window button:active
|
||||
.bm-window button:disabled {
|
||||
background-color: #2e97ff;
|
||||
}
|
||||
|
||||
/* All window buttons when disabled */
|
||||
.bm-window button:disabled, .bm-window button:disabled {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
/* Icon buttons (single character text content buttons) */
|
||||
.bm-button-circle {
|
||||
border: white 1px solid;
|
||||
height: 1.5em;
|
||||
width: 1.5em;
|
||||
margin-top: 2px;
|
||||
text-align: center;
|
||||
line-height: 1em;
|
||||
padding: 0 !important; /* Overrides the padding in ".bm-window button" */
|
||||
}
|
||||
|
||||
/* Window content container */
|
||||
.bm-window-content {
|
||||
overflow: hidden;
|
||||
transition: height 300ms cubic-bezier(.4, 0, .2, 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* The entire overlay */
|
||||
#bm-overlay, #bm-overlay-telemetry {
|
||||
position: fixed;
|
||||
|
|
|
|||
|
|
@ -213,6 +213,7 @@ export default class TemplateManager {
|
|||
const coords = tile.split(','); // [x, y, x, y] Tile/pixel coordinates
|
||||
|
||||
return {
|
||||
instance: template,
|
||||
bitmap: template.chunked[tile],
|
||||
chunked32: template.chunked32?.[tile],
|
||||
tileCoords: [coords[0], coords[1]],
|
||||
|
|
@ -316,7 +317,7 @@ export default class TemplateManager {
|
|||
}
|
||||
console.log(`Finished calculating correct pixels for the tile ${tileCoords} in ${(Date.now() - timer) / 1000} seconds!\nThere are ${pixelsCorrectTotal} correct pixels.`);
|
||||
|
||||
template.pixelCount['correct'] = pixelsCorrect; // Adds the correct pixel Map to the template instance
|
||||
template.instance.pixelCount['correct'] = pixelsCorrect; // Adds the correct pixel Map to the template instance
|
||||
}
|
||||
|
||||
return await canvas.convertToBlob({ type: 'image/png' });
|
||||
|
|
|
|||
Loading…
Reference in a new issue