mirror of
https://github.com/SwingTheVine/Wplace-BlueMarble.git
synced 2026-04-20 14:22:05 +00:00
Partially working template
This commit is contained in:
parent
6face92136
commit
fe62f14357
8 changed files with 104 additions and 58 deletions
4
dist/BlueMarble.user.js
vendored
4
dist/BlueMarble.user.js
vendored
File diff suppressed because one or more lines are too long
|
|
@ -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-294-black?style=flat"></a>
|
||||
<a href="" target="_blank"><img alt="Total Patches" src="https://img.shields.io/badge/Total_Patches-327-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-70.19%25-blue"></a>
|
||||
|
|
|
|||
4
package-lock.json
generated
4
package-lock.json
generated
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "wplace-bluemarble",
|
||||
"version": "0.63.20",
|
||||
"version": "0.63.53",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "wplace-bluemarble",
|
||||
"version": "0.63.20",
|
||||
"version": "0.63.53",
|
||||
"devDependencies": {
|
||||
"esbuild": "^0.25.0",
|
||||
"terser": "^5.43.1"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "wplace-bluemarble",
|
||||
"version": "0.63.20",
|
||||
"version": "0.63.53",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "node build/build.js",
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// ==UserScript==
|
||||
// @name Blue Marble
|
||||
// @namespace https://github.com/SwingTheVine/
|
||||
// @version 0.63.20
|
||||
// @version 0.63.53
|
||||
// @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
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ export default class ApiManager {
|
|||
spontaneousResponseListener(overlay) {
|
||||
|
||||
// Triggers whenever a message is sent
|
||||
window.addEventListener('message', (event) => {
|
||||
window.addEventListener('message', async (event) => {
|
||||
|
||||
const data = event.data; // The data of the message
|
||||
const dataJSON = data['jsonData']; // The JSON response, if any
|
||||
|
|
@ -110,12 +110,26 @@ export default class ApiManager {
|
|||
const blobUUID = data['blobID'];
|
||||
const blobData = data['blobData'];
|
||||
|
||||
const gojo = this.templateManager.drawGojo();
|
||||
let templateBlob = blobData; // By default, apply no template
|
||||
|
||||
console.log(`templateState: ${this.templateManager.templateState || null}`);
|
||||
|
||||
// Only apply the template if a template is loaded
|
||||
// Otherwise, draw the template so the next attempted load will not need a re-draw
|
||||
switch (this.templateManager.templateState) {
|
||||
case 'file': // Draw the template
|
||||
console.log(`Attempting to draw template...`);
|
||||
templateBlob = await this.templateManager.drawTemplate(blobData);
|
||||
break;
|
||||
case 'template': // The template is already processed, pass it in
|
||||
templateBlob = this.templateManager.template;
|
||||
break;
|
||||
}
|
||||
|
||||
window.postMessage({
|
||||
source: 'blue-marble',
|
||||
blobID: blobUUID,
|
||||
blobData: gojo,
|
||||
blobData: templateBlob,
|
||||
blink: data['blink']
|
||||
});
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -239,8 +239,6 @@ function buildOverlayMain() {
|
|||
|
||||
templateManager.setTemplateImage(input.files[0]);
|
||||
|
||||
templateManager.tempDraw();
|
||||
console.log(templateManager.canvasTemplate);
|
||||
instance.handleDisplayStatus(`Drew to canvas!`);
|
||||
}
|
||||
}).buildElement()
|
||||
|
|
|
|||
|
|
@ -10,10 +10,6 @@ export default class TemplateManager {
|
|||
this.canvasTemplate = null; // Our canvas
|
||||
this.canvasTemplateID = 'bm-canvas'; // Our canvas ID
|
||||
this.canvasMainID = 'div#map canvas.maplibregl-canvas'; // The selector for the main canvas
|
||||
this.canvasMainMap = window.__bm_interceptedMap;
|
||||
this.onMove = this.onMove.bind(this); // Binds the handler for `move` to this class instance's function
|
||||
this.onResize = this.onResize.bind(this); // Binds the handler for `resize` to this class instance's function
|
||||
this.onZoom = this.onZoom.bind(this); // Binds the handler for `zoom` to this class instance's function
|
||||
this.template = null; // The template image.
|
||||
this.templateState = ''; // The state of the template ('blob', 'proccessing', 'template', etc.)
|
||||
}
|
||||
|
|
@ -23,6 +19,7 @@ export default class TemplateManager {
|
|||
* @param {string} selector - The CSS selector to use to find the canvas.
|
||||
* @returns {HTMLCanvasElement|null} The canvas as an HTML Canvas Element, or null if the canvas does not exist
|
||||
* @since 0.58.3
|
||||
* @deprecated Not in use since 0.63.25
|
||||
*/
|
||||
getCanvas() {
|
||||
|
||||
|
|
@ -66,57 +63,94 @@ export default class TemplateManager {
|
|||
this.template = file;
|
||||
this.templateState = 'file';
|
||||
|
||||
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
|
||||
// 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
|
||||
}
|
||||
|
||||
tempDraw() {
|
||||
const ctx = this.getCanvas(this.canvasTemplateID)?.getContext('2d');
|
||||
if (ctx) {
|
||||
function drawLoop() {
|
||||
ctx.fillStyle = 'red';
|
||||
ctx.fillRect(10, 10, 100, 100);
|
||||
//ctx.setTransform(1, 0, 0, 1, -21511, -1305644);
|
||||
//requestAnimationFrame(drawLoop);
|
||||
}
|
||||
drawLoop();
|
||||
}
|
||||
}
|
||||
async drawTemplate(tileBlob) {
|
||||
|
||||
drawGojo() {
|
||||
// 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
|
||||
|
||||
// const [templateBitmap, tileBitmap] = await Promise.all([
|
||||
// createImageBitmap(await this.shrinkPixelsInPlace(this.template)),
|
||||
// createImageBitmap(tileBlob)
|
||||
// ]);
|
||||
|
||||
if (this.templateState != 'file') {return;}
|
||||
// If the template has already been drawn, don't draw it again
|
||||
console.log(this.template);
|
||||
const templateBitmap = this.templateState == 'template' ? this.template : await createImageBitmap(await this.shreadBlob(this.template));
|
||||
const tileBitmap = await createImageBitmap(tileBlob);
|
||||
|
||||
return this.template;
|
||||
const canvas = new OffscreenCanvas(drawSize, drawSize);
|
||||
const context = canvas.getContext('2d');
|
||||
|
||||
context.imageSmoothingEnabled = false; // Nearest neighbor
|
||||
|
||||
context.clearRect(0, 0, drawSize, drawSize); // Draws transparent background
|
||||
context.drawImage(templateBitmap, 0, 0); // TODO: Change X Y here
|
||||
context.drawImage(tileBitmap, 0, 0, drawSize, drawSize);
|
||||
|
||||
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
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/** What to do to our canvas when the canvas is panned.
|
||||
* @since 0.60.10
|
||||
/** Shreads the blob so that every pixel is surrounded by adjacent transparent pixels
|
||||
* @param {Blob|File} blob - The blob to manipulate
|
||||
* @param {number} [shrinkFactor=3] - An odd number that will place each pixel in the center. Even numbers will be increased by 1
|
||||
* @param {string} [fileType='image/png'] - The File type to output as. PNG is one of the few transparent types.
|
||||
* @returns {Promise<File>} - A Promise that resolved to a image/png file blob
|
||||
* @since 0.63.37
|
||||
*/
|
||||
onMove() {
|
||||
this.tempDraw();
|
||||
console.log(this.canvasMainMap);
|
||||
}
|
||||
async shreadBlob(blob, shreadSize = 3, fileType = 'image/png') {
|
||||
|
||||
const bitmap = await createImageBitmap(blob); // Creates a bitmap image
|
||||
|
||||
/** What to do to our canvas when the canvas is zoomes.
|
||||
* @since 0.60.11
|
||||
*/
|
||||
onZoom() {
|
||||
this.tempDraw();
|
||||
}
|
||||
shreadSize |= 1; // Converts shreadSize to always be odd by forcing the right-most bit to be 1.
|
||||
|
||||
/** What to do to our canvas when the viewport is resized.
|
||||
* @since 0.60.10
|
||||
*/
|
||||
onResize() {
|
||||
const canvasMain = document.querySelector(this.canvasMainID);
|
||||
const canvasTemplate = this.getCanvas();
|
||||
if (!canvasTemplate || !canvasMain) {return;}
|
||||
canvasTemplate.style.height = `${canvasMain?.clientHeight * (window.devicePixelRatio || 1)}px`;
|
||||
canvasTemplate.style.width = `${canvasMain?.clientWidth * (window.devicePixelRatio || 1)}px`;
|
||||
canvasTemplate.height = canvasMain?.clientHeight * (window.devicePixelRatio || 1);
|
||||
canvasTemplate.width = canvasMain?.clientWidth * (window.devicePixelRatio || 1);
|
||||
this.tempDraw();
|
||||
const width = bitmap.width * Math.round(shreadSize); // Width of the canvas based on shread size times blob
|
||||
const height = bitmap.height * Math.round(shreadSize); // Height of the canvas based on shread size times blob
|
||||
|
||||
const canvas = document.createElement('canvas'); // Creates a canvas
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
const context = canvas.getContext('2d'); // Gets the context of the canvas
|
||||
context.imageSmoothingEnabled = false; // Nearest Neighbor scaling
|
||||
|
||||
context.drawImage(bitmap, 0, 0, width, height); // Fills the canvas with the blob
|
||||
|
||||
const imageData = context.getImageData(0, 0, width, height); // Data of the image on the canvas
|
||||
|
||||
for (let y = 0; y < height; y++) {
|
||||
for (let x = 0; x < width; x++) {
|
||||
// For every pixel...
|
||||
|
||||
// ... Make it transparent unless it is the "center"
|
||||
if ((x % shreadSize !== 1) || (y % shreadSize !== 1)) {
|
||||
const pixelIndex = (y * width + x) * 4; // Find the pixel index in an array where every 4 indexes are 1 pixel
|
||||
imageData.data[pixelIndex + 3] = 0; // Make the pixel transparent on the alpha channel
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
context.putImageData(imageData, 0, 0);
|
||||
return new Promise((resolve) => {canvas.toBlob(resolve, fileType);});
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue