Added drag capability

This commit is contained in:
SwingTheVine 2026-02-15 01:19:45 -05:00
parent 8bc6bd2855
commit 63889a4c02
10 changed files with 89 additions and 76 deletions

View file

@ -2,7 +2,7 @@
// @name Blue Marble
// @name:en Blue Marble
// @namespace https://github.com/SwingTheVine/
// @version 0.88.122
// @version 0.88.123
// @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
@ -523,8 +523,9 @@
}
/** Handles dragging of the overlay.
* Uses requestAnimationFrame for smooth animations and GPU-accelerated transforms.
* @param {string} moveMe - The ID of the element to be moved
* @param {string} iMoveThings - The ID of the drag handle element
* Use the appropriate CSS selectors.
* @param {string} moveMe - The element to be moved
* @param {string} iMoveThings - The drag handle element
* @since 0.8.2
*/
handleDrag(moveMe, iMoveThings) {
@ -535,8 +536,9 @@
let currentY = 0;
let targetX = 0;
let targetY = 0;
moveMe = document.querySelector(moveMe?.[0] == "#" ? moveMe : "#" + moveMe);
iMoveThings = document.querySelector(iMoveThings?.[0] == "#" ? iMoveThings : "#" + iMoveThings);
let initialRect = null;
moveMe = document.querySelector(moveMe);
iMoveThings = document.querySelector(iMoveThings);
if (!moveMe || !iMoveThings) {
this.handleDisplayError(`Can not drag! ${!moveMe ? "moveMe" : ""} ${!moveMe && !iMoveThings ? "and " : ""}${!iMoveThings ? "iMoveThings " : ""}was not found!`);
return;
@ -556,7 +558,6 @@
animationFrame = requestAnimationFrame(updatePosition);
}
};
let initialRect = null;
const startDrag = (clientX, clientY) => {
isDragging = true;
initialRect = moveMe.getBoundingClientRect();
@ -575,7 +576,12 @@
targetX = currentX;
targetY = currentY;
document.body.style.userSelect = "none";
iMoveThings.classList.add("dragging");
iMoveThings.classList.add("bm-dragging");
document.addEventListener("mousemove", onMouseMove);
document.addEventListener("touchmove", onTouchMove, { passive: false });
document.addEventListener("mouseup", endDrag);
document.addEventListener("touchend", endDrag);
document.addEventListener("touchcancel", endDrag);
if (animationFrame) {
cancelAnimationFrame(animationFrame);
}
@ -588,7 +594,27 @@
animationFrame = null;
}
document.body.style.userSelect = "";
iMoveThings.classList.remove("dragging");
iMoveThings.classList.remove("bm-dragging");
document.removeEventListener("mousemove", onMouseMove);
document.removeEventListener("touchmove", onTouchMove);
document.removeEventListener("mouseup", endDrag);
document.removeEventListener("touchend", endDrag);
document.removeEventListener("touchcancel", endDrag);
};
const onMouseMove = (event) => {
if (isDragging && initialRect) {
targetX = event.clientX - offsetX;
targetY = event.clientY - offsetY;
}
};
const onTouchMove = (event) => {
if (isDragging && initialRect) {
const touch = event.touches[0];
if (!touch) return;
targetX = touch.clientX - offsetX;
targetY = touch.clientY - offsetY;
event.preventDefault();
}
};
iMoveThings.addEventListener("mousedown", function(event) {
event.preventDefault();
@ -602,26 +628,6 @@
startDrag(touch.clientX, touch.clientY);
event.preventDefault();
}, { passive: false });
document.addEventListener("mousemove", function(event) {
if (isDragging && initialRect) {
targetX = event.clientX - offsetX;
targetY = event.clientY - offsetY;
}
}, { passive: true });
document.addEventListener("touchmove", function(event) {
if (isDragging && initialRect) {
const touch = event?.touches?.[0];
if (!touch) {
return;
}
targetX = touch.clientX - offsetX;
targetY = touch.clientY - offsetY;
event.preventDefault();
}
}, { passive: false });
document.addEventListener("mouseup", endDrag);
document.addEventListener("touchend", endDrag);
document.addEventListener("touchcancel", endDrag);
}
/** Handles status display.
* This will output plain text into the output Status box.
@ -1659,7 +1665,7 @@ Time Since Blink: ${String(Math.floor(elapsed / 6e4)).padStart(2, "0")}:${String
buildTelemetryOverlay(telemetryOverlay);
}
buildOverlayMain();
overlayMain.handleDrag("#bm-overlay", "#bm-bar-drag");
overlayMain.handleDrag("#bm-window-main.bm-window", "#bm-window-main .bm-dragbar");
apiManager.spontaneousResponseListener(overlayMain);
observeBlack();
consoleLog(`%c${name}%c (${version}) userscript has loaded!`, "color: cornflowerblue;", "");
@ -1692,7 +1698,7 @@ Time Since Blink: ${String(Math.floor(elapsed / 6e4)).padStart(2, "0")}:${String
observer.observe(document.body, { childList: true, subtree: true });
}
function buildOverlayMain() {
overlayMain.addDiv({ "class": "bm-window", "style": "top: 10px; right: 75px;" }).addDiv({ "class": "bm-dragbar" }).addDiv().addButton({ "class": "bm-button-circle", "textContent": "\u25BC" }, (instance, button) => {
overlayMain.addDiv({ "id": "bm-window-main", "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");

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -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-620-black?style=flat"></a>
<a href="" target="_blank" rel="noopener noreferrer"><img alt="Total Patches" src="https://img.shields.io/badge/Total_Patches-621-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
View file

@ -1,12 +1,12 @@
{
"name": "wplace-bluemarble",
"version": "0.88.122",
"version": "0.88.123",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "wplace-bluemarble",
"version": "0.88.122",
"version": "0.88.123",
"devDependencies": {
"esbuild": "^0.25.0",
"jsdoc": "^4.0.5",

View file

@ -1,6 +1,6 @@
{
"name": "wplace-bluemarble",
"version": "0.88.122",
"version": "0.88.123",
"type": "module",
"homepage": "https://bluemarble.lol/",
"repository": {

View file

@ -2,7 +2,7 @@
// @name Blue Marble
// @name:en Blue Marble
// @namespace https://github.com/SwingTheVine/
// @version 0.88.122
// @version 0.88.123
// @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

View file

@ -594,8 +594,9 @@ export default class Overlay {
/** Handles dragging of the overlay.
* Uses requestAnimationFrame for smooth animations and GPU-accelerated transforms.
* @param {string} moveMe - The ID of the element to be moved
* @param {string} iMoveThings - The ID of the drag handle element
* Use the appropriate CSS selectors.
* @param {string} moveMe - The element to be moved
* @param {string} iMoveThings - The drag handle element
* @since 0.8.2
*/
handleDrag(moveMe, iMoveThings) {
@ -606,10 +607,11 @@ export default class Overlay {
let currentY = 0;
let targetX = 0;
let targetY = 0;
let initialRect = null; // Cache initial position to avoid expensive getBoundingClientRect calls during drag
// Retrieves the elements (allows either '#id' or 'id' to be passed in)
moveMe = document.querySelector(moveMe?.[0] == '#' ? moveMe : '#' + moveMe);
iMoveThings = document.querySelector(iMoveThings?.[0] == '#' ? iMoveThings : '#' + iMoveThings);
moveMe = document.querySelector(moveMe);
iMoveThings = document.querySelector(iMoveThings);
// What to do when one of the two elements are not found
if (!moveMe || !iMoveThings) {
@ -638,9 +640,6 @@ export default class Overlay {
animationFrame = requestAnimationFrame(updatePosition);
}
};
// Cache initial position to avoid expensive getBoundingClientRect calls during drag
let initialRect = null;
const startDrag = (clientX, clientY) => {
isDragging = true;
@ -665,7 +664,14 @@ export default class Overlay {
targetY = currentY;
document.body.style.userSelect = 'none';
iMoveThings.classList.add('dragging');
iMoveThings.classList.add('bm-dragging');
// Add move listeners when dragging starts
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('touchmove', onTouchMove, { passive: false });
document.addEventListener('mouseup', endDrag);
document.addEventListener('touchend', endDrag);
document.addEventListener('touchcancel', endDrag);
// Start animation loop
if (animationFrame) {
@ -681,7 +687,33 @@ export default class Overlay {
animationFrame = null;
}
document.body.style.userSelect = '';
iMoveThings.classList.remove('dragging');
iMoveThings.classList.remove('bm-dragging');
// Remove move listeners when drag ends
document.removeEventListener('mousemove', onMouseMove);
document.removeEventListener('touchmove', onTouchMove);
document.removeEventListener('mouseup', endDrag);
document.removeEventListener('touchend', endDrag);
document.removeEventListener('touchcancel', endDrag);
};
// Mouse move
const onMouseMove = event => {
if (isDragging && initialRect) {
targetX = event.clientX - offsetX;
targetY = event.clientY - offsetY;
}
}
// Touch move
const onTouchMove = event => {
if (isDragging && initialRect) {
const touch = event.touches[0];
if (!touch) return;
targetX = touch.clientX - offsetX;
targetY = touch.clientY - offsetY;
event.preventDefault();
}
};
// Mouse down - start dragging
@ -697,30 +729,6 @@ export default class Overlay {
startDrag(touch.clientX, touch.clientY);
event.preventDefault();
}, { passive: false });
// Mouse move - update target position
document.addEventListener('mousemove', function(event) {
if (isDragging && initialRect) {
targetX = event.clientX - offsetX;
targetY = event.clientY - offsetY;
}
}, { passive: true });
// Touch move - update target position
document.addEventListener('touchmove', function(event) {
if (isDragging && initialRect) {
const touch = event?.touches?.[0];
if (!touch) {return;}
targetX = touch.clientX - offsetX;
targetY = touch.clientY - offsetY;
event.preventDefault();
}
}, { passive: false });
// End drag events
document.addEventListener('mouseup', endDrag);
document.addEventListener('touchend', endDrag);
document.addEventListener('touchcancel', endDrag);
}
/** Handles status display.

View file

@ -218,8 +218,7 @@ if ((userSettings?.telemetry == undefined) || (userSettings?.telemetry > 1)) { /
}
buildOverlayMain(); // Builds the main overlay
overlayMain.handleDrag('#bm-overlay', '#bm-bar-drag'); // Creates dragging capability on the drag bar for dragging the overlay
overlayMain.handleDrag('#bm-window-main.bm-window', '#bm-window-main .bm-dragbar'); // Creates dragging capability on the drag bar for dragging the overlay
apiManager.spontaneousResponseListener(overlayMain); // Reads spontaneous fetch responces
@ -274,7 +273,7 @@ function observeBlack() {
*/
function buildOverlayMain() {
overlayMain.addDiv({'class': 'bm-window', 'style': 'top: 10px; right: 75px;'})
overlayMain.addDiv({'id': 'bm-window-main', 'class': 'bm-window', 'style': 'top: 10px; right: 75px;'})
.addDiv({'class': 'bm-dragbar'})
.addDiv()
.addButton({'class': 'bm-button-circle', 'textContent': '▼'}, (instance, button) => {