Add coordinate prediction
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { faCamera, faCaretDown, faCaretUp, faPieChart, faUpload } from "@fortawesome/free-solid-svg-icons";
|
import { faCamera, faCaretDown, faCaretUp, faLocationCrosshairs, faPieChart, faUpload } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
@@ -83,6 +83,7 @@ interface Props {
|
|||||||
interface State {
|
interface State {
|
||||||
takingCanvasShot: boolean;
|
takingCanvasShot: boolean;
|
||||||
canvasShotAvailable: boolean;
|
canvasShotAvailable: boolean;
|
||||||
|
locationPrecision: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Menu extends React.Component<Props, State> {
|
export class Menu extends React.Component<Props, State> {
|
||||||
@@ -92,6 +93,7 @@ export class Menu extends React.Component<Props, State> {
|
|||||||
this.state = {
|
this.state = {
|
||||||
takingCanvasShot: false,
|
takingCanvasShot: false,
|
||||||
canvasShotAvailable: true,
|
canvasShotAvailable: true,
|
||||||
|
locationPrecision: props.cords.highPrecision
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,11 +118,15 @@ export class Menu extends React.Component<Props, State> {
|
|||||||
Popup.alert(error.name);
|
Popup.alert(error.name);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inputElement = (event: React.FormEvent<HTMLInputElement>) => {
|
inputElement = (event: React.FormEvent<HTMLInputElement>) => {
|
||||||
const percentage = parseInt((event.target as HTMLInputElement).value);
|
const percentage = parseInt((event.target as HTMLInputElement).value);
|
||||||
this.props.onOpacityChange(percentage);
|
this.props.onOpacityChange(percentage);
|
||||||
};
|
};
|
||||||
|
togglePrecision = () => {
|
||||||
|
const value = !this.state.locationPrecision;
|
||||||
|
this.setState({ locationPrecision: value });
|
||||||
|
this.props.cords.toggleHigherPrecision(value);
|
||||||
|
};
|
||||||
screenshot = async () => {
|
screenshot = async () => {
|
||||||
if (this.props.cords.uScale < 0) {
|
if (this.props.cords.uScale < 0) {
|
||||||
//Popup.alert("Cannot take screenshot at sc")
|
//Popup.alert("Cannot take screenshot at sc")
|
||||||
@@ -148,6 +154,14 @@ export class Menu extends React.Component<Props, State> {
|
|||||||
onClick={() => this.props.showChart()}
|
onClick={() => this.props.showChart()}
|
||||||
title="Pixels graph">
|
title="Pixels graph">
|
||||||
<FontAwesomeIcon icon={ faPieChart } />
|
<FontAwesomeIcon icon={ faPieChart } />
|
||||||
|
</Btn>
|
||||||
|
<Btn
|
||||||
|
title="Runtime coordinate calculator. Uses more resources"
|
||||||
|
onClick={this.togglePrecision}
|
||||||
|
style={{
|
||||||
|
border: this.state.locationPrecision ? "" : "2px dotted black"
|
||||||
|
}}>
|
||||||
|
<FontAwesomeIcon icon={ faLocationCrosshairs } />
|
||||||
</Btn>
|
</Btn>
|
||||||
<InputRange type="range" min={0} max={100} value={this.props.opacity} onInput={this.inputElement} />
|
<InputRange type="range" min={0} max={100} value={this.props.opacity} onInput={this.inputElement} />
|
||||||
<PercentageDiv>{this.props.opacity}%</PercentageDiv>
|
<PercentageDiv>{this.props.opacity}%</PercentageDiv>
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ export class Overlay extends React.Component<Props, State> {
|
|||||||
|
|
||||||
this.ref.current!.style.top = this.ref.current!.style.left = `0px`;
|
this.ref.current!.style.top = this.ref.current!.style.left = `0px`;
|
||||||
this.props.cords.on(CordType.Url, this.draw);
|
this.props.cords.on(CordType.Url, this.draw);
|
||||||
|
this.props.cords.on(CordType.UrlPredict, this.draw);
|
||||||
this.props.cords.on(CordType.Div, this.updateIfMouseDown);
|
this.props.cords.on(CordType.Div, this.updateIfMouseDown);
|
||||||
window.addEventListener("mousemove", this.onMouseMove);
|
window.addEventListener("mousemove", this.onMouseMove);
|
||||||
window.addEventListener("touchmove", this.onTouchMove);
|
window.addEventListener("touchmove", this.onTouchMove);
|
||||||
@@ -60,6 +61,7 @@ export class Overlay extends React.Component<Props, State> {
|
|||||||
}
|
}
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
this.props.cords.off(CordType.Url, this.draw);
|
this.props.cords.off(CordType.Url, this.draw);
|
||||||
|
this.props.cords.off(CordType.UrlPredict, this.draw);
|
||||||
this.props.cords.off(CordType.Div, this.updateIfMouseDown);
|
this.props.cords.off(CordType.Div, this.updateIfMouseDown);
|
||||||
window.removeEventListener("mousemove", this.onMouseMove);
|
window.removeEventListener("mousemove", this.onMouseMove);
|
||||||
window.removeEventListener("touchmove", this.onTouchMove);
|
window.removeEventListener("touchmove", this.onTouchMove);
|
||||||
|
|||||||
+1
-1
@@ -18,7 +18,7 @@ async function main() {
|
|||||||
await store.load();
|
await store.load();
|
||||||
const injector = new Injector(store);
|
const injector = new Injector(store);
|
||||||
await injector.inject();
|
await injector.inject();
|
||||||
const coordinates = new Coordinates(injector);
|
const coordinates = new Coordinates(injector, store);
|
||||||
await coordinates.init();
|
await coordinates.init();
|
||||||
|
|
||||||
createUI(store,storage, coordinates, palette);
|
createUI(store,storage, coordinates, palette);
|
||||||
|
|||||||
+82
-53
@@ -1,11 +1,14 @@
|
|||||||
import { CHUNK_SIZE } from "../constants";
|
import { CHUNK_SIZE } from "../constants";
|
||||||
|
import { CoordinatePredictor } from "./coordinatesPredictor";
|
||||||
import { Listener, BasicEventEmitter } from "./eventEmitter";
|
import { Listener, BasicEventEmitter } from "./eventEmitter";
|
||||||
import { InjectEvents, Injector } from "./injector";
|
import { InjectEvents, Injector } from "./injector";
|
||||||
|
import { Store } from "./store";
|
||||||
import { waitForDraw } from "./utils";
|
import { waitForDraw } from "./utils";
|
||||||
|
|
||||||
export enum CordType {
|
export enum CordType {
|
||||||
Div,
|
Div,
|
||||||
Url
|
Url,
|
||||||
|
UrlPredict
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Coordinates {
|
export class Coordinates {
|
||||||
@@ -20,66 +23,90 @@ export class Coordinates {
|
|||||||
private _uy = 0;
|
private _uy = 0;
|
||||||
private _uScale = 0;
|
private _uScale = 0;
|
||||||
private down?: number[];
|
private down?: number[];
|
||||||
|
private coordinatePredictor: CoordinatePredictor;
|
||||||
|
private _highPrecision = false;
|
||||||
//div: HTMLDivElement;
|
//div: HTMLDivElement;
|
||||||
constructor(injector: Injector) {
|
constructor(injector: Injector, private storage: Store) {
|
||||||
injector.on(InjectEvents.UrlChange, url => {
|
injector.on(InjectEvents.UrlChange, url => {
|
||||||
this.onUrlCordsUpdate(url);
|
this.onUrlCordsUpdate(url);
|
||||||
});
|
});
|
||||||
this.onUrlCordsUpdate();
|
this.onUrlCordsUpdate();
|
||||||
|
this.coordinatePredictor = new CoordinatePredictor(this, (x, y, scale) => {
|
||||||
window.addEventListener("touchstart", (event) => {
|
this._ux = Math.round(x);
|
||||||
if (event.target instanceof HTMLCanvasElement && event.touches.length === 1) {
|
this._uy = Math.round(y);
|
||||||
this.down = [event.touches[0].clientX, event.touches[0].clientY, this.ux, this.uy];
|
this._uScale = Math.round(scale);
|
||||||
}
|
this.emitter.emit(CordType.UrlPredict, x, y, scale);
|
||||||
});
|
});
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toggleHigherPrecision(value: boolean) {
|
||||||
|
if (this._highPrecision === value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (value) {
|
||||||
|
this.coordinatePredictor.enable();
|
||||||
|
window.removeEventListener("touchstart", this.touchStart);
|
||||||
|
window.removeEventListener("touchmove", this.touchMove);
|
||||||
|
window.removeEventListener("touchend", this.endMovement);
|
||||||
|
window.removeEventListener("mousedown", this.mouseDown);
|
||||||
|
window.removeEventListener("mousemove", this.mouseMove);
|
||||||
|
window.removeEventListener("mouseup", this.endMovement);
|
||||||
|
} else {
|
||||||
|
this.coordinatePredictor.disable();
|
||||||
|
window.addEventListener("touchstart", this.touchStart);
|
||||||
|
window.addEventListener("touchmove", this.touchMove);
|
||||||
|
window.addEventListener("touchend", this.endMovement);
|
||||||
|
window.addEventListener("mousedown", this.mouseDown);
|
||||||
|
window.addEventListener("mousemove", this.mouseMove);
|
||||||
|
window.addEventListener("mouseup", this.endMovement);
|
||||||
|
}
|
||||||
|
this.storage.toggleHighPrecision(value);
|
||||||
|
this._highPrecision = value;
|
||||||
|
}
|
||||||
|
get highPrecision() {
|
||||||
|
return this._highPrecision;
|
||||||
|
}
|
||||||
|
|
||||||
|
private touchStart = (event: TouchEvent) => {
|
||||||
|
if (event.target instanceof HTMLCanvasElement && event.touches.length === 1) {
|
||||||
|
this.down = [event.touches[0].clientX, event.touches[0].clientY, this.ux, this.uy];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
private touchMove = (event: TouchEvent) => {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
private mouseDown = (event: MouseEvent) => {
|
||||||
|
if (event.target instanceof HTMLCanvasElement) {
|
||||||
|
this.down = [event.x, event.y, this.ux, this.uy];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
private mouseMove = (event: MouseEvent) => {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
private endMovement = () => {
|
||||||
|
this.down = undefined;
|
||||||
|
};
|
||||||
|
|
||||||
on(event: CordType, listener: Listener<[number, number, number]>) {
|
on(event: CordType, listener: Listener<[number, number, number]>) {
|
||||||
this.emitter.on(event, listener);
|
this.emitter.on(event, listener);
|
||||||
}
|
}
|
||||||
@@ -105,6 +132,8 @@ export class Coordinates {
|
|||||||
}
|
}
|
||||||
await waitForDraw();
|
await waitForDraw();
|
||||||
}
|
}
|
||||||
|
const value = await this.storage.enabledHighPrecision();
|
||||||
|
this.toggleHigherPrecision(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
stop() {
|
stop() {
|
||||||
|
|||||||
@@ -0,0 +1,166 @@
|
|||||||
|
import { CHUNK_SIZE } from "../constants";
|
||||||
|
import { Coordinates, CordType } from "./coordinates";
|
||||||
|
|
||||||
|
export class CoordinatePredictor {
|
||||||
|
private frame?: number;
|
||||||
|
tileRef?: HTMLCanvasElement;
|
||||||
|
private lastX?: number;
|
||||||
|
private lastY?: number;
|
||||||
|
private lastScale?: number;
|
||||||
|
private cords: number[];
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private coordinates: Coordinates,
|
||||||
|
private predict: (x: number, y: number, scale: number) => void
|
||||||
|
) {
|
||||||
|
coordinates.on(CordType.Url, (x, y, scale) => {
|
||||||
|
if (this.cords) {
|
||||||
|
this.cords[0] = x;
|
||||||
|
this.cords[1] = y;
|
||||||
|
this.cords[2] = scale;
|
||||||
|
} else {
|
||||||
|
this.cords = [x, y, scale];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private cordUpdate = (x: number, y: number, s: number) => {
|
||||||
|
this.cords = [x, y, s];
|
||||||
|
};
|
||||||
|
syncCords() {
|
||||||
|
const cords = this.coordinates;
|
||||||
|
this.cordUpdate(cords.ux, cords.uy, cords.uScale);
|
||||||
|
}
|
||||||
|
enable() {
|
||||||
|
if (this.frame)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.syncCords();
|
||||||
|
this.coordinates.on(CordType.Url, this.cordUpdate);
|
||||||
|
this.frame = requestAnimationFrame(this.tick);
|
||||||
|
}
|
||||||
|
disable() {
|
||||||
|
if (this.frame) {
|
||||||
|
this.coordinates.off(CordType.Url, this.cordUpdate);
|
||||||
|
cancelAnimationFrame(this.frame);
|
||||||
|
this.frame = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
get enabled() {
|
||||||
|
return !!this.frame;
|
||||||
|
}
|
||||||
|
tick = () => {
|
||||||
|
if (!this.tileRef || !document.body.contains(this.tileRef)) {
|
||||||
|
this.tileRef = [...document.getElementsByTagName("canvas")]
|
||||||
|
.find(e => e.classList.contains("leaflet-tile"));
|
||||||
|
|
||||||
|
if (this.tileRef) {
|
||||||
|
const rect = this.tileRef?.getBoundingClientRect();
|
||||||
|
if (rect) {
|
||||||
|
this.syncCords();
|
||||||
|
this.lastScale = this.getScale(rect.width);
|
||||||
|
this.lastX = rect?.left;
|
||||||
|
this.lastY = rect?.top;
|
||||||
|
}
|
||||||
|
this.nextFrame();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const rect = this.tileRef?.getBoundingClientRect();
|
||||||
|
if (rect) {
|
||||||
|
if (this.lastX != null && this.lastY != null && this.lastScale != null) {
|
||||||
|
const scale = this.getScale(rect.width);
|
||||||
|
const x = rect?.left;
|
||||||
|
const y = rect?.top;
|
||||||
|
if (x !== this.lastX || y !== this.lastY || scale != this.lastScale) {
|
||||||
|
const mx = this.lastX - rect?.left;
|
||||||
|
const my = this.lastY - rect?.top;
|
||||||
|
//const ms = this.lastScale - this.lastScale;
|
||||||
|
// console.log(this.lastX - rect?.left, this.lastY - rect?.top, scale);
|
||||||
|
// console.log(x / this.lastScale);
|
||||||
|
// console.log(y / this.lastScale);
|
||||||
|
this.lastX = x;
|
||||||
|
this.lastY = y;
|
||||||
|
this.lastScale = scale;
|
||||||
|
this.cords[0] += (mx / (rect.width / CHUNK_SIZE));
|
||||||
|
this.cords[1] += (my / (rect.width / CHUNK_SIZE));
|
||||||
|
this.predict(this.cords[0], this.cords[1], this.cords[2]);
|
||||||
|
this.cords[2] = scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
this.nextFrame();
|
||||||
|
};
|
||||||
|
|
||||||
|
private nextFrame() {
|
||||||
|
if (this.frame) {
|
||||||
|
this.frame = requestAnimationFrame(this.tick);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private getScale(width: number) {
|
||||||
|
const scale = width / CHUNK_SIZE;
|
||||||
|
return Math.log(scale) / Math.log(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// private get centerCanvas() {
|
||||||
|
// const hww = window.innerWidth / 2;
|
||||||
|
// const hhw = window.innerHeight / 2;
|
||||||
|
// const canvasObject = [
|
||||||
|
// ...document.getElementsByTagName("canvas")]
|
||||||
|
// .filter(c => c.classList.contains("leaflet-tile"))
|
||||||
|
// .map(c => {
|
||||||
|
// const bounds = c.getBoundingClientRect();
|
||||||
|
// return {
|
||||||
|
// canvas: c,
|
||||||
|
// bounds: {
|
||||||
|
// width: bounds.width,
|
||||||
|
// height: bounds.height,
|
||||||
|
// top: bounds.top,
|
||||||
|
// bottom: bounds.bottom,
|
||||||
|
// left: bounds.left,
|
||||||
|
// right: bounds.right,
|
||||||
|
// },
|
||||||
|
// };
|
||||||
|
// }).find(r => hww > r.bounds.left && hww < r.bounds.right && hhw > r.bounds.top && hhw < r.bounds.bottom);
|
||||||
|
|
||||||
|
// if (canvasObject) {
|
||||||
|
// const ratio = canvasObject.canvas.width / CHUNK_SIZE;
|
||||||
|
// if (ratio === 2) { // scale -1
|
||||||
|
// const hw = canvasObject.bounds.left + canvasObject.bounds.width / 2;
|
||||||
|
// const hh = canvasObject.bounds.top + canvasObject.bounds.height / 2;
|
||||||
|
// const chunkW = CHUNK_SIZE / canvasObject.canvas.width;
|
||||||
|
// const chunkH = CHUNK_SIZE / canvasObject.canvas.height;
|
||||||
|
// canvasObject.bounds.width = chunkW;
|
||||||
|
// canvasObject.bounds.height = chunkH;
|
||||||
|
|
||||||
|
// if (hww <= hw && hhw <= hh) {
|
||||||
|
// // top left
|
||||||
|
// } else if (hww > hw && hhw < hh) {
|
||||||
|
// // top right
|
||||||
|
// canvasObject.bounds.top += chunkW;
|
||||||
|
// } else if (hww > hw && hhw > hh) {
|
||||||
|
// // bottom left
|
||||||
|
// canvasObject.bounds.left += chunkH;
|
||||||
|
// } else {
|
||||||
|
// // bottom left right
|
||||||
|
// canvasObject.bounds.left += chunkW;
|
||||||
|
// canvasObject.bounds.top += chunkH;
|
||||||
|
// }
|
||||||
|
// canvasObject.bounds.bottom = canvasObject.bounds.top + chunkW;
|
||||||
|
// canvasObject.bounds.right = canvasObject.bounds.left + chunkH;
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
// canvasObject.bounds.width /= ratio;
|
||||||
|
// canvasObject.bounds.height /= ratio;
|
||||||
|
// canvasObject.bounds.right = canvasObject.bounds.left + canvasObject.bounds.width;
|
||||||
|
// canvasObject.bounds.bottom = canvasObject.bounds.bottom + canvasObject.bounds.height;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return canvasObject;
|
||||||
|
// }
|
||||||
|
}
|
||||||
+8
-1
@@ -38,10 +38,10 @@ export interface PixelLogEx extends PixelLog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class Store implements LoadUnload {
|
export class Store implements LoadUnload {
|
||||||
|
private readonly STORAGE_KEY_HIGH_PRECISION = "_high-precision";
|
||||||
private readonly STORAGE_KEY_MURAL = "_murals";
|
private readonly STORAGE_KEY_MURAL = "_murals";
|
||||||
private readonly STORAGE_KEY_SELECTED = "_mural";
|
private readonly STORAGE_KEY_SELECTED = "_mural";
|
||||||
private readonly STORAGE_KEY_LOG_STORE = "records";
|
private readonly STORAGE_KEY_LOG_STORE = "records";
|
||||||
private readonly STORAGE_KEY_PIXEL_LOG = "_pixel-log";
|
|
||||||
private _murals: MuralEx[] = [];
|
private _murals: MuralEx[] = [];
|
||||||
private _selected?: MuralEx;
|
private _selected?: MuralEx;
|
||||||
private emitter = new BasicEventEmitter();
|
private emitter = new BasicEventEmitter();
|
||||||
@@ -290,6 +290,13 @@ export class Store implements LoadUnload {
|
|||||||
this.emit(StoreEvents.MuralPhantomOverlay);
|
this.emit(StoreEvents.MuralPhantomOverlay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async enabledHighPrecision() {
|
||||||
|
return (await this.storage.getItem<boolean>(this.STORAGE_KEY_HIGH_PRECISION)) ?? false;
|
||||||
|
}
|
||||||
|
toggleHighPrecision(value: boolean) {
|
||||||
|
return this.storage.setItem(this.STORAGE_KEY_HIGH_PRECISION, value);
|
||||||
|
}
|
||||||
get murals() {
|
get murals() {
|
||||||
return this._murals;
|
return this._murals;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user