mirror of
https://github.com/SwingTheVine/Wplace-BlueMarble.git
synced 2026-04-20 01:52:03 +00:00
Template Overlay now appears above tile...
...and you can't move the template when placing pixels anymore xd
This commit is contained in:
parent
c5c1ddd157
commit
b0a98ee4a0
11 changed files with 118 additions and 17 deletions
4
dist/BlueMarble.user.js
vendored
4
dist/BlueMarble.user.js
vendored
File diff suppressed because one or more lines are too long
|
|
@ -23,4 +23,5 @@ The favicon "Blue Marble" is owned by NASA
|
|||
|
||||
Special Thanks:
|
||||
* nof, [darkness](https://github.com/TouchedByDarkness) for creating similar userscripts!
|
||||
* [BullStein](https://github.com/BullStein), [allanf181](https://github.com/allanf181) for being early beta testers!
|
||||
* TheBlueCorner for getting me interested in online pixel canvases!
|
||||
|
|
@ -35,7 +35,7 @@
|
|||
<a href="https://github.com/SwingTheVine/Wplace-BlueMarble/blob/main/LICENSE.txt" target="_blank"><img alt="Software License: MPL-2.0" src="https://img.shields.io/badge/Software_License-MPL--2.0-brightgreen?style=flat"></a>
|
||||
<a href="https://discord.gg/tpeBPy46hf" target="_blank"><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="" target="_blank"><img alt="WakaTime" src="https://img.shields.io/badge/Coding_Time-59hrs_0mins-blue?style=flat&logo=wakatime&logoColor=black&logoSize=auto&labelColor=white"></a>
|
||||
<a href="" target="_blank"><img alt="Total Patches" src="https://img.shields.io/badge/Total_Patches-342-black?style=flat"></a>
|
||||
<a href="" target="_blank"><img alt="Total Patches" src="https://img.shields.io/badge/Total_Patches-354-black?style=flat"></a>
|
||||
<a href="" target="_blank"><img alt="Total Lines of Code" src="https://tokei.rs/b1/github/SwingTheVine/Wplace-BlueMarble?category=code"></a>
|
||||
<a href="" target="_blank"><img alt="Total Comments" src="https://tokei.rs/b1/github/SwingTheVine/Wplace-BlueMarble?category=comments"></a>
|
||||
<a href="" target="_blank"><img alt="Compression" src="https://img.shields.io/badge/Compression-71.26%25-blue"></a>
|
||||
|
|
|
|||
4
package-lock.json
generated
4
package-lock.json
generated
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "wplace-bluemarble",
|
||||
"version": "0.63.68",
|
||||
"version": "0.64.12",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "wplace-bluemarble",
|
||||
"version": "0.63.68",
|
||||
"version": "0.64.12",
|
||||
"devDependencies": {
|
||||
"esbuild": "^0.25.0",
|
||||
"terser": "^5.43.1"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "wplace-bluemarble",
|
||||
"version": "0.64.0",
|
||||
"version": "0.64.12",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "node build/build.js",
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// ==UserScript==
|
||||
// @name Blue Marble
|
||||
// @namespace https://github.com/SwingTheVine/
|
||||
// @version 0.64.0
|
||||
// @version 0.64.12
|
||||
// @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.
|
||||
// @author SwingTheVine
|
||||
// @license MPL-2.0
|
||||
|
|
|
|||
|
|
@ -3,17 +3,22 @@
|
|||
* @since 0.0.2
|
||||
* @example
|
||||
* const overlay = new Overlay();
|
||||
* overlay.addDiv('overlay')
|
||||
* .addHeader(1, {'textContent': 'Your Overlay'}).buildElement()
|
||||
* .addP({'textContent': 'This is your overlay. It is versatile.'}).buildElement()
|
||||
* overlay.addDiv({ 'id': 'overlay' })
|
||||
* .addDiv({ 'id': 'header' })
|
||||
* .addHeader(1, {'textContent': 'Your Overlay'}).buildElement()
|
||||
* .addP({'textContent': 'This is your overlay. It is versatile.'}).buildElement()
|
||||
* .buildElement() // Marks the end of the header <div>
|
||||
* .addHr().buildElement()
|
||||
* .buildOverlay(document.body);
|
||||
* // Output:
|
||||
* // (Assume <body> already exists in the webpage)
|
||||
* <body>
|
||||
* <div id="overlay">
|
||||
* <h1>Your Overlay</h1>
|
||||
* <p>This is your overlay. It is versatile.</p>
|
||||
* <div id="header">
|
||||
* <h1>Your Overlay</h1>
|
||||
* <p>This is your overlay. It is versatile.</p>
|
||||
* </div>
|
||||
* <hr>
|
||||
* </div>
|
||||
* </body>
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,86 @@
|
|||
/** An instance of a template.
|
||||
* Handles all mathmatics and manipulation regarding a single template.
|
||||
* @since 0.65.2
|
||||
*/
|
||||
export default class Template {
|
||||
|
||||
/** The constructor for the {@link Template} class.
|
||||
* @since 0.65.2
|
||||
*/
|
||||
constructor() {
|
||||
this.templateName = ''; // The name of the template
|
||||
this.templateFile = null; // The template file. This can be a pre-processed File, or a processed bitmap
|
||||
this.templateState = ''; // The state of the template file. This is how you tell if it is a File, bitmap, or nothing
|
||||
this.templateCoords = null; // The coordinates of the top left corner as (x, y, x, y)
|
||||
this.templateChunked = null; // The affected chunks of the template, and their template for each chunk
|
||||
}
|
||||
|
||||
/** Sets the template to the image passed in.
|
||||
* @param {File} file - The file of the template image.
|
||||
* @since 0.65.2
|
||||
*/
|
||||
setTemplateImage(file) {
|
||||
|
||||
this.templateName = file.name.replace(/\.[^/.]+$/, ''); // "foo.bar.png" -> "foo.bar"
|
||||
this.template = file; // Overrides The previous template image/bitmap with the new image
|
||||
this.templateState = 'file'; // Indicates that the template is now an image (not a bitmap)
|
||||
|
||||
// const url = URL.createObjectURL(file); // Creates a blob URL
|
||||
// window.open(url, '_blank'); // Opens a new tab with blob
|
||||
// setTimeout(() => URL.revokeObjectURL(url), 10000); // Destroys the blob 10 seconds later
|
||||
}
|
||||
|
||||
/** Draws the template on the tile. Returns the tile plus the overlay.
|
||||
* @param {File|Blob} tileBlob - The blob of the tile
|
||||
* @param {Array<number, number, number, number>} [coordsTilePixel=[0,0,0,0]] - A number array of the four coordinates
|
||||
* @returns {File|Blob} A image/png blob file
|
||||
* @since 0.63.59
|
||||
*/
|
||||
async drawTemplate(tileBlob, coordsTilePixel=[0, 0, 0, 0]) {
|
||||
|
||||
// Only continue if template state is NOT 'file' NOR 'template'
|
||||
if (!((this.templateState == 'file') || (this.templateState == 'template'))) {return;}
|
||||
|
||||
const tileSize = 1000; // Pixels in a tile
|
||||
const drawMult = 3; // Multiplier of draw size
|
||||
const drawSize = tileSize * drawMult; // Draw multiplier
|
||||
|
||||
coordsTilePixel = !!coordsTilePixel?.length ? coordsTilePixel : [0, 0, 0, 0]; // Set to default if [] passed in
|
||||
|
||||
console.log(this.template);
|
||||
// If the template has already been drawn, don't draw it again
|
||||
const templateBitmap = this.templateState == 'template' ? this.template : await createImageBitmap(await this.shreadBlob(this.template));
|
||||
const tileBitmap = await createImageBitmap(tileBlob);
|
||||
|
||||
const canvas = new OffscreenCanvas(drawSize, drawSize);
|
||||
const context = canvas.getContext('2d');
|
||||
|
||||
context.imageSmoothingEnabled = false; // Nearest neighbor scaleing
|
||||
context.globalCompositeOperation = "destination-over"; // If we the image we are drawing has transparent pixels, don't preserve them.
|
||||
|
||||
// Tells the canvas to ignore anything outside of this area
|
||||
context.beginPath();
|
||||
context.rect(0, 0, drawSize, drawSize);
|
||||
context.clip();
|
||||
|
||||
context.clearRect(0, 0, drawSize, drawSize); // Draws transparent background
|
||||
context.drawImage(tileBitmap, 0, 0, drawSize, drawSize); // Draws the tile
|
||||
context.drawImage(templateBitmap, coordsTilePixel[2]*3, coordsTilePixel[3]*3); // Draws the template on top of the tile
|
||||
|
||||
const final = await canvas.convertToBlob({ type: 'image/png' });
|
||||
|
||||
// If the template is not drawn yet...
|
||||
if (this.templateState != 'template') {
|
||||
// (99% chance templateState is 'file')
|
||||
|
||||
this.template = templateBitmap; // Store the drawn template
|
||||
this.templateState = 'template'; // Indicate that the template has been drawn, and this.template now stores a bitmap
|
||||
|
||||
// const url = URL.createObjectURL(final); // Creates a blob URL
|
||||
// window.open(url, '_blank'); // Opens a new tab with blob
|
||||
// setTimeout(() => URL.revokeObjectURL(url), 10000); // Destroys the blob 10 seconds later
|
||||
}
|
||||
|
||||
return final;
|
||||
}
|
||||
}
|
||||
|
|
@ -16,6 +16,7 @@ export default class ApiManager {
|
|||
this.templateManager = templateManager;
|
||||
this.disableAll = false; // Should the entire userscript be disabled?
|
||||
this.coordsTilePixel = []; // Contains the last detected tile/pixel coordinate pair requested
|
||||
this.templateCoordsTilePixel = []; // Contains the last "enabled" template coords
|
||||
}
|
||||
|
||||
/** Determines if the spontaneously recieved response is something we want.
|
||||
|
|
@ -107,7 +108,7 @@ export default class ApiManager {
|
|||
|
||||
case 'tiles':
|
||||
|
||||
// Runs only if the tile has the a template
|
||||
// Runs only if the tile has the template
|
||||
let tileCoordsTile = data['endpoint'].split('/');
|
||||
tileCoordsTile = [parseInt(tileCoordsTile[tileCoordsTile.length - 2]), parseInt(tileCoordsTile[tileCoordsTile.length - 1].replace('.png', ''))];
|
||||
|
||||
|
|
@ -115,10 +116,14 @@ export default class ApiManager {
|
|||
const blobData = data['blobData'];
|
||||
let templateBlob = blobData; // By default, apply no template
|
||||
|
||||
if ((tileCoordsTile[0] == this.coordsTilePixel[0]) && (tileCoordsTile[1] == this.coordsTilePixel[1])) {
|
||||
// Only run if all coordinates are there
|
||||
if (this.templateCoordsTilePixel?.length >= 4) {
|
||||
|
||||
console.log(`templateState: ${this.templateManager.templateState || null}`);
|
||||
templateBlob = !!this.templateManager.templateState ? await this.templateManager.drawTemplate(blobData, this.coordsTilePixel) : blobData;
|
||||
if ((tileCoordsTile[0] == this.templateCoordsTilePixel[0]) && (tileCoordsTile[1] == this.templateCoordsTilePixel[1])) {
|
||||
|
||||
console.log(`templateState: ${this.templateManager.templateState || null}`);
|
||||
templateBlob = !!this.templateManager.templateState ? await this.templateManager.drawTemplate(blobData, this.templateCoordsTilePixel) : blobData;
|
||||
}
|
||||
}
|
||||
|
||||
window.postMessage({
|
||||
|
|
|
|||
|
|
@ -237,6 +237,9 @@ function buildOverlayMain() {
|
|||
// Kills itself if there is no file
|
||||
if (!input?.files[0]) {instance.handleDisplayError(`No file selected!`); return;}
|
||||
|
||||
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!`);
|
||||
|
|
|
|||
|
|
@ -102,8 +102,9 @@ export default class TemplateManager {
|
|||
context.clip();
|
||||
|
||||
context.clearRect(0, 0, drawSize, drawSize); // Draws transparent background
|
||||
context.drawImage(templateBitmap, coordsTilePixel[2]*3, coordsTilePixel[3]*3);
|
||||
context.drawImage(tileBitmap, 0, 0, drawSize, drawSize);
|
||||
//context.globalCompositeOperation = "destination-atop"; // If we the image we are drawing has transparent pixels, don't preserve them.
|
||||
context.drawImage(templateBitmap, coordsTilePixel[2]*3, coordsTilePixel[3]*3);
|
||||
|
||||
const final = await canvas.convertToBlob({ type: 'image/png' });
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue