diff --git a/dist/user-script.user.js b/dist/user-script.user.js index f74b5a5..4d113e9 100644 --- a/dist/user-script.user.js +++ b/dist/user-script.user.js @@ -53768,18 +53768,117 @@ } }; + // src/lib/injector.ts + var Injector = class { + constructor(store) { + this.store = store; + } + eventEmitter = new BasicEventEmitter(); + inject() { + const api2 = document.createElement("script"); + api2.addEventListener("load", () => { + document.body.removeChild(api2); + }, { once: true }); + api2.addEventListener("error", (error) => { + console.error(error); + }); + return new Promise((resolve, reject) => { + const d2 = document; + api2.addEventListener("error", (error) => { + reject(error.error); + }, { once: true }); + d2.addEventListener(EVENT_CROSS_WORLD_INJECTED, () => { + resolve(); + }, { once: true }); + if (false) { + api2.src = chrome.runtime.getURL("/assets/scripts/inject.js"); + } else { + api2.textContent = INJECT_SCRIPT_PIXEL_OBSERVER; + } + document.body.appendChild(api2); + d2.addEventListener(EVENT_CROSS_WORLD_PIXEL_PLACED, (event) => { + const body = event.detail; + if (typeof body === "object" && "x" in body && "y" in body && "color" in body && typeof body.color === "number" && typeof body.x === "number" && typeof body.y === "number") { + this.store.addPixelLog(body.x, body.y, body.color); + this.eventEmitter.emit(1 /* PixelPlaced */, body); + } + }); + d2.addEventListener(EVENT_CROSS_WORLD_URL_UPDATE, (event) => { + const body = event.detail; + if (typeof body === "string") { + this.eventEmitter.emit(2 /* UrlChange */, body); + } + }); + }); + } + on(event, cb) { + this.eventEmitter.on(event, cb); + return this; + } + off(event, cb) { + this.eventEmitter.off(event, cb); + return this; + } + }; + // src/lib/coordinates.ts var Coordinates = class { cords; emitter = new BasicEventEmitter(); + observer; _x = 0; _y = 0; frame; _ux = 0; _uy = 0; _uScale = 0; + down; //div: HTMLDivElement; - constructor() { + constructor(injector) { + injector.on(2 /* UrlChange */, (url) => { + this.onUrlCordsUpdate(url); + }); + this.onUrlCordsUpdate(); + window.addEventListener("touchstart", (event) => { + if (event.target instanceof HTMLCanvasElement && event.touches.length === 1) { + this.down = [event.touches[0].clientX, event.touches[0].clientY, this.ux, this.uy]; + } + }); + window.addEventListener("touchmove", (event) => { + if (this.down && event.touches.length === 1) { + const mx = Math.round((this.down[0] - event.touches[0].clientX) / Math.pow(2, this._uScale)); + const my = Math.round((this.down[1] - event.touches[0].clientY) / Math.pow(2, this._uScale)); + const ux = this._ux; + const uy = this._uy; + this._ux = this.down[2] + mx, this._uy = this.down[3] + my; + if (ux !== this._ux || uy !== this._uy) { + this.emitter.emit(1 /* Url */, this._ux, this._uy, this._uScale); + } + } + }); + window.addEventListener("touchend", () => { + this.down = void 0; + }); + window.addEventListener("mousedown", (event) => { + if (event.target instanceof HTMLCanvasElement) { + this.down = [event.x, event.y, this.ux, this.uy]; + } + }); + window.addEventListener("mousemove", (event) => { + if (this.down) { + const mx = Math.round((this.down[0] - event.x) / Math.pow(2, this._uScale)); + const my = Math.round((this.down[1] - event.y) / Math.pow(2, this._uScale)); + const ux = this._ux; + const uy = this._uy; + this._ux = this.down[2] + mx, this._uy = this.down[3] + my; + if (ux !== this._ux || uy !== this._uy) { + this.emitter.emit(1 /* Url */, this._ux, this._uy, this._uScale); + } + } + }); + window.addEventListener("mouseup", () => { + this.down = void 0; + }); } on(event, listener3) { this.emitter.on(event, listener3); @@ -53793,15 +53892,22 @@ for (const cord of cords) { if (cord.children.length === 0) { this.cords = cord; - this.frame = requestAnimationFrame(this.observe); + this.observer = new MutationObserver(() => { + this.updateDivCords(); + }); + this.observer.observe(cord, { + characterData: true, + subtree: true + }); + break; } } await waitForDraw(); } } stop() { - if (this.frame) { - cancelAnimationFrame(this.frame); + if (this.observer) { + this.observer.disconnect(); } } get centerCanvas() { @@ -53859,7 +53965,6 @@ const c3 = this.centerCanvas; if (!c3) return null; - this.getCordsFromUrl(); const chunkX = Math.floor(this.ux / CHUNK_SIZE) * CHUNK_SIZE; const chunkY = Math.floor(this.uy / CHUNK_SIZE) * CHUNK_SIZE; const xx = (sx - c3.bounds.left) / this.pixelSize + chunkX; @@ -53878,9 +53983,9 @@ const y3 = c3.bounds.top + screenY * this.pixelSize; return { x: x3, y: y3 }; } - getCordsFromUrl() { + updateURLcords(url) { const pathNames = location.pathname.split("/").filter((e) => e); - const cordsRaw = pathNames[0]; + const cordsRaw = url || pathNames[0]; if (cordsRaw) { const cordsMatch = cordsRaw.match(/-?\d+/g); if (cordsMatch) { @@ -53891,7 +53996,6 @@ this._uScale = cords[2]; return cords; } - console.log(cordsMatch); } } return null; @@ -53901,22 +54005,24 @@ this._x = arr[0]; this._y = arr[1]; } - observe = () => { + updateDivCords() { const x3 = this._x; const y3 = this._y; this.parse(); if (x3 !== this._x || y3 !== this._y) { this.emitter.emit(0 /* Div */, this._x, this._y); } + } + onUrlCordsUpdate(url) { const ux = this._ux; const uy = this._uy; const uScale = this._uScale; - this.getCordsFromUrl(); + this.updateURLcords(url); + this.down = void 0; if (ux !== this._ux || uy !== this._uy || uScale !== this._uScale) { this.emitter.emit(1 /* Url */, this._ux, this._uy, this._uScale); } - this.frame = requestAnimationFrame(this.observe); - }; + } get x() { return this._x; } @@ -53932,6 +54038,9 @@ get uScale() { return this._uScale; } + get dragging() { + return !!this.down; + } }; // src/lib/palette.ts @@ -58556,7 +58665,7 @@ this.resize(); this.ref.current.style.top = this.ref.current.style.left = `0px`; this.props.cords.on(1 /* Url */, this.draw); - console.log("test"); + this.props.cords.on(0 /* Div */, this.updateIfMouseDown); window.addEventListener("mousemove", this.onMouseMove); window.addEventListener("touchmove", this.onTouchMove); window.addEventListener("resize", this.resize); @@ -58570,10 +58679,16 @@ } componentWillUnmount() { this.props.cords.off(1 /* Url */, this.draw); + this.props.cords.off(0 /* Div */, this.updateIfMouseDown); window.removeEventListener("mousemove", this.onMouseMove); window.removeEventListener("touchmove", this.onTouchMove); window.removeEventListener("resize", this.resize); } + updateIfMouseDown = () => { + if (this.props.cords.dragging) { + this.draw(); + } + }; onMouseMove = (event) => { if (event.buttons === 1) { this.draw(); @@ -58596,7 +58711,6 @@ }; componentDidUpdate(prevProps, prevState) { if (prevProps.muralExtended !== this.props.muralExtended) { - this._refImage = void 0; this.setState({ x: 0, y: 0 @@ -77396,61 +77510,6 @@ // src/index.ts var import_process = __toESM(require_browser2()); - - // src/lib/injector.ts - var Injector = class { - constructor(store) { - this.store = store; - } - eventEmitter = new BasicEventEmitter(); - inject() { - const api2 = document.createElement("script"); - api2.addEventListener("load", () => { - document.body.removeChild(api2); - }, { once: true }); - api2.addEventListener("error", (error) => { - console.error(error); - }); - return new Promise((resolve, reject) => { - const d2 = document; - api2.addEventListener("error", (error) => { - reject(error.error); - }, { once: true }); - d2.addEventListener(EVENT_CROSS_WORLD_INJECTED, () => { - resolve(); - }, { once: true }); - if (false) { - api2.src = chrome.runtime.getURL("/assets/scripts/inject.js"); - } else { - api2.textContent = INJECT_SCRIPT_PIXEL_OBSERVER; - } - document.body.appendChild(api2); - d2.addEventListener(EVENT_CROSS_WORLD_PIXEL_PLACED, (event) => { - const body = event.detail; - if (typeof body === "object" && "x" in body && "y" in body && "color" in body && typeof body.color === "number" && typeof body.x === "number" && typeof body.y === "number") { - this.store.addPixelLog(body.x, body.y, body.color); - this.eventEmitter.emit(1 /* PixelPlaced */, body); - } - }); - d2.addEventListener(EVENT_CROSS_WORLD_URL_UPDATE, (event) => { - const body = event.detail; - if (typeof body === "string") { - this.eventEmitter.emit(2 /* UrlChange */, body); - } - }); - }); - } - on(event, cb) { - this.eventEmitter.on(event, cb); - return this; - } - off(event, cb) { - this.eventEmitter.off(event, cb); - return this; - } - }; - - // src/index.ts async function main() { globalThis.process = import_process.default; const palette = new Palette(); @@ -77462,7 +77521,7 @@ await store.load(); const injector = new Injector(store); await injector.inject(); - const coordinates = new Coordinates(); + const coordinates = new Coordinates(injector); await coordinates.init(); createUI(store, storage, coordinates, palette); console.log( diff --git a/src/UI/components/overlay.tsx b/src/UI/components/overlay.tsx index bc85e0c..4c26fc3 100644 --- a/src/UI/components/overlay.tsx +++ b/src/UI/components/overlay.tsx @@ -45,9 +45,8 @@ export class Overlay extends React.Component { this.resize(); this.ref.current!.style.top = this.ref.current!.style.left = `0px`; - this.props.cords.on(CordType.Url, this.draw); - console.log("test"); + this.props.cords.on(CordType.Div, this.updateIfMouseDown); window.addEventListener("mousemove", this.onMouseMove); window.addEventListener("touchmove", this.onTouchMove); window.addEventListener("resize", this.resize); @@ -61,11 +60,16 @@ export class Overlay extends React.Component { } componentWillUnmount() { this.props.cords.off(CordType.Url, this.draw); - + this.props.cords.off(CordType.Div, this.updateIfMouseDown); window.removeEventListener("mousemove", this.onMouseMove); window.removeEventListener("touchmove", this.onTouchMove); window.removeEventListener("resize", this.resize); } + updateIfMouseDown = () => { + if (this.props.cords.dragging) { + this.draw(); + } + }; onMouseMove = (event: MouseEvent) => { if (event.buttons === 1) { this.draw(); @@ -91,7 +95,6 @@ export class Overlay extends React.Component { componentDidUpdate(prevProps: Readonly, prevState: Readonly) { if (prevProps.muralExtended !== this.props.muralExtended) { - this._refImage = undefined; this.setState({ x: 0, y: 0 }); diff --git a/src/index.ts b/src/index.ts index 1a68440..06aa91b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -18,7 +18,7 @@ async function main() { await store.load(); const injector = new Injector(store); await injector.inject(); - const coordinates = new Coordinates(); + const coordinates = new Coordinates(injector); await coordinates.init(); createUI(store,storage, coordinates, palette); diff --git a/src/lib/coordinates.ts b/src/lib/coordinates.ts index 35e04df..5a28d91 100644 --- a/src/lib/coordinates.ts +++ b/src/lib/coordinates.ts @@ -1,5 +1,6 @@ import { CHUNK_SIZE } from "../constants"; import { Listener, BasicEventEmitter } from "./eventEmitter"; +import { InjectEvents, Injector } from "./injector"; import { waitForDraw } from "./utils"; export enum CordType { @@ -10,6 +11,7 @@ export enum CordType { export class Coordinates { private cords: HTMLDivElement; private emitter = new BasicEventEmitter(); + private observer: MutationObserver; private _x = 0; private _y = 0; private frame: number; @@ -17,15 +19,65 @@ export class Coordinates { private _ux = 0; private _uy = 0; private _uScale = 0; + private down?: number[]; //div: HTMLDivElement; - constructor() { - // this.div = document.createElement("div"); - // this.div.style.position = "fixed"; - // this.div.style.backgroundColor = "orange"; - // document.body.appendChild(this.div); - // this.div.style.opacity = "0.75"; - // this.div.style.zIndex = "10px"; - // this.div.style.pointerEvents = "none"; + constructor(injector: Injector) { + injector.on(InjectEvents.UrlChange, url => { + this.onUrlCordsUpdate(url); + }); + this.onUrlCordsUpdate(); + + window.addEventListener("touchstart", (event) => { + if (event.target instanceof HTMLCanvasElement && event.touches.length === 1) { + this.down = [event.touches[0].clientX, event.touches[0].clientY, this.ux, this.uy]; + } + }); + window.addEventListener("touchmove", event => { + if (this.down && event.touches.length === 1) { + const mx = Math.round((this.down[0] - event.touches[0].clientX) / Math.pow(2, this._uScale)); + const my = Math.round((this.down[1] - event.touches[0].clientY) / Math.pow(2, this._uScale)); + const ux = this._ux; + const uy = this._uy; + this._ux = this.down[2] + mx, + this._uy = this.down[3] + my; + if (ux !== this._ux || uy !== this._uy) { + this.emitter.emit(CordType.Url, this._ux, this._uy, this._uScale); + } + } + }); + window.addEventListener("touchend", () => { + this.down = undefined; + }); + window.addEventListener("mousedown", event => { + if (event.target instanceof HTMLCanvasElement) { + this.down = [event.x, event.y, this.ux, this.uy]; + } + }); + window.addEventListener("mousemove", event => { + if (this.down) { + const mx = Math.round((this.down[0] - event.x) / Math.pow(2, this._uScale)); + const my = Math.round((this.down[1] - event.y) / Math.pow(2, this._uScale)); + const ux = this._ux; + const uy = this._uy; + this._ux = this.down[2] + mx, + this._uy = this.down[3] + my; + if (ux !== this._ux || uy !== this._uy) { + this.emitter.emit(CordType.Url, this._ux, this._uy, this._uScale); + } + } + }); + window.addEventListener("mouseup", () => { + this.down = undefined; + }); + + // window.addEventListener("wheel" , event => { + // const s = this._uScale; + // if (event.deltaY > 0) { + // this._uScale = s / 2; + // } else { + // this._uScale = s * 2; + // } + // }, true); } on(event: CordType, listener: Listener<[number, number, number]>) { @@ -41,7 +93,14 @@ export class Coordinates { for (const cord of cords) { if (cord.children.length === 0) { this.cords = cord; - this.frame = requestAnimationFrame(this.observe); + this.observer = new MutationObserver(() => { + this.updateDivCords(); + }); + this.observer.observe(cord, { + characterData: true, + subtree: true, + }); + break; } } await waitForDraw(); @@ -49,8 +108,8 @@ export class Coordinates { } stop() { - if (this.frame) { - cancelAnimationFrame(this.frame); + if (this.observer) { + this.observer.disconnect(); } } @@ -116,7 +175,6 @@ export class Coordinates { screenToGrid(sx: number, sy: number) { const c = this.centerCanvas; if (!c) return null; - this.getCordsFromUrl(); const chunkX = Math.floor(this.ux / CHUNK_SIZE) * CHUNK_SIZE; const chunkY = Math.floor(this.uy / CHUNK_SIZE) * CHUNK_SIZE; const xx = ((sx - c.bounds.left) / this.pixelSize) + chunkX; @@ -127,7 +185,6 @@ export class Coordinates { gridToScreen(gridX: number, gridY: number) { const c = this.centerCanvas; if (!c) return null; - const chunkX = Math.floor(this.ux / CHUNK_SIZE) * CHUNK_SIZE; const chunkY = Math.floor(this.uy / CHUNK_SIZE) * CHUNK_SIZE; const screenX = (gridX - chunkX); @@ -138,9 +195,9 @@ export class Coordinates { return { x, y }; } - getCordsFromUrl() { + updateURLcords(url?: string) { const pathNames = location.pathname.split("/").filter(e => e); - const cordsRaw = pathNames[0]; + const cordsRaw = url || pathNames[0]; if (cordsRaw) { const cordsMatch = cordsRaw.match(/-?\d+/g); if (cordsMatch) { @@ -151,7 +208,6 @@ export class Coordinates { this._uScale = cords[2]; return cords; } - console.log(cordsMatch); } } return null; @@ -163,7 +219,7 @@ export class Coordinates { this._y = arr[1]; } - observe = () => { + updateDivCords() { const x = this._x; const y = this._y; this.parse(); @@ -171,17 +227,18 @@ export class Coordinates { if (x !== this._x || y !== this._y) { this.emitter.emit(CordType.Div, this._x, this._y); } - + } + onUrlCordsUpdate(url?: string) { const ux = this._ux; const uy = this._uy; const uScale = this._uScale; - this.getCordsFromUrl(); + this.updateURLcords(url); + this.down = undefined; if (ux !== this._ux || uy !== this._uy || uScale !== this._uScale) { this.emitter.emit(CordType.Url, this._ux, this._uy, this._uScale); } + } - this.frame = requestAnimationFrame(this.observe); - }; get x() { return this._x; } @@ -198,4 +255,7 @@ export class Coordinates { get uScale() { return this._uScale; } + get dragging() { + return !!this.down; + } } \ No newline at end of file