Optimize overlay

This commit is contained in:
2025-02-13 17:15:37 +01:00
parent 5587dd7909
commit 75994c110d
4 changed files with 75 additions and 35 deletions
+1 -1
View File
@@ -146,7 +146,7 @@ export class Main extends React.Component<Props, State> {
muralExtended={this.props.store.murals[this.state.phantomOverlay]}
/> : null }
{this.state.overlayModify ? <Overlay
muralObj={this.state.overlayModify.muralObj}
muralModifier={this.state.overlayModify.muralModify}
opacity={this.state.opacity}
storage={this.props.storage}
cords={this.props.cords}
+64 -28
View File
@@ -6,7 +6,6 @@ import { Palette } from "../../lib/palette";
import { MovableWindow } from "./movableWindow";
import { Storage } from "../../lib/storage";
import { MuralEditor } from "./muralEditor";
import { Mural } from "../../lib/mural";
const Canvas = styled.canvas`
position: fixed;
@@ -15,9 +14,9 @@ const Canvas = styled.canvas`
`;
interface Props {
muralExtended: MuralEx;
muralObj?: Partial<Mural>;
onChange?: (name: string, x: number, y:number, confirm?: boolean) => void;
muralExtended: Readonly<MuralEx>;
muralModifier?: { x: number, y: number, name: string };
onChange?: (name: string, x: number, y: number, confirm?: boolean) => void;
cords: Coordinates;
storage: Storage;
palette: Palette;
@@ -32,7 +31,6 @@ interface State {
export class Overlay extends React.Component<Props, State> {
private ref = React.createRef<HTMLCanvasElement>();
private _refImage?: HTMLCanvasElement;
constructor(props: Props) {
super(props);
@@ -44,21 +42,52 @@ export class Overlay extends React.Component<Props, State> {
}
componentDidMount() {
this.draw();
this.resize();
this.ref.current!.style.top = this.ref.current!.style.left = `0px`;
this.props.cords.on(CordType.Url, this.draw);
window.addEventListener("mousemove", this.draw);
if (this.props.muralObj) {
console.log("test");
window.addEventListener("mousemove", this.onMouseMove);
window.addEventListener("touchmove", this.onTouchMove);
window.addEventListener("resize", this.resize);
if (this.props.muralModifier) {
this.setState({
name: this.props.muralObj.name || "",
x: this.props.muralObj.x ?? 0,
y: this.props.muralObj.y ?? 0,
name: this.props.muralModifier.name || "",
x: this.props.muralModifier.x ?? 0,
y: this.props.muralModifier.y ?? 0,
});
}
}
componentWillUnmount() {
this.props.cords.off(CordType.Url, this.draw);
window.removeEventListener("mousemove", this.draw);
window.removeEventListener("mousemove", this.onMouseMove);
window.removeEventListener("touchmove", this.onTouchMove);
window.removeEventListener("resize", this.resize);
}
onMouseMove = (event: MouseEvent) => {
if (event.buttons === 1) {
this.draw();
}
};
onTouchMove = (event: TouchEvent) => {
if (event.touches.length) {
this.draw();
}
};
resize = () => {
const canvas = this.ref.current!;
if (canvas.height !== window.outerHeight || canvas.width !== window.outerWidth) {
canvas.width = window.outerWidth;
canvas.height = window.outerHeight;
canvas.style.width = `${window.outerWidth}px`;
canvas.style.height = `${window.outerHeight}px`;
this.draw();
}
};
componentDidUpdate(prevProps: Readonly<Props>, prevState: Readonly<State>) {
if (prevProps.muralExtended !== this.props.muralExtended) {
@@ -78,11 +107,11 @@ export class Overlay extends React.Component<Props, State> {
}
get x() {
return this.props.muralExtended.mural.x;
return this.props.muralModifier ? this.state.x : this.props.muralExtended.mural.x;
}
get y() {
return this.props.muralExtended.mural.y;
return this.props.muralModifier ? this.state.y : this.props.muralExtended.mural.y;
}
get refImg() {
@@ -92,33 +121,40 @@ export class Overlay extends React.Component<Props, State> {
draw = () => {
const canvas = this.ref.current!;
const scale = Math.pow(2, this.props.cords.uScale);
// TODO calculate cords differently to be less expensive
// TODO also add cache
// TODO also profile the thing
const cords = this.props.cords.gridToScreen(this.x, this.y)!;
if (!cords) {
const ctx = canvas.getContext("2d")!;
ctx.clearRect(0, 0, canvas.width, canvas.height);
return;
}
const { x, y } = cords;
const x = cords.x;
const y = cords.y;
const width = this.props.muralExtended.mural.w * scale;
const height = this.props.muralExtended.mural.h * scale;
if (width !== canvas.width || height !== canvas.height ) {
canvas.width = width;
canvas.height = height;
canvas.style.width = `${width}px`;
canvas.style.height = `${height}px`;
}
const ctx = canvas.getContext("2d")!;
ctx.imageSmoothingEnabled = false;
canvas.style.left = `${x}px`;
canvas.style.top = `${y}px`;
ctx.drawImage(this.refImg, 0, 0, canvas.width, canvas.height);
const ctx = canvas.getContext("2d")!;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.imageSmoothingEnabled = false;
ctx.drawImage(this.refImg, x, y, width, height);
// if (true) {
// ctx.strokeStyle = "#000000";
// ctx.strokeText(`${x}px ${y}px`, 11, 11);
// ctx.strokeText(`${x}px ${y}px`, 9, 9);
// ctx.strokeText(`${x}px ${y}px`, 9, 11);
// ctx.strokeText(`${x}px ${y}px`, 11, 9);
// ctx.fillStyle = "#ffffff";
// ctx.fillText(`${x}px ${y}px`, 10, 10);
// }
};
private get style(): React.CSSProperties {
return { left: this.state.x, top: this.state.y, opacity: this.props.opacity / 100};
return { opacity: this.props.opacity / 100};
}
renderModifyWindow() {
@@ -153,4 +189,4 @@ export class Overlay extends React.Component<Props, State> {
{this.renderModifyWindow()}
</>;
}
}
}
+9 -5
View File
@@ -1,7 +1,7 @@
import React from "react";
import { ImportOutput, MuralOld, RGB } from "../interfaces";
import { canvasToImageData, convertOldMuralToNewMural, getColorScore, getExtension,
import { canvasToImageData, convertOldMuralToNewMural, createMuralExtended, getColorScore, getExtension,
imageDataToPaletteIndices, imageToCanvas, loadImageSource, processNumberEvent,
readAsArrayBuffer,
readAsDataUrl, readAsString, resize, rgb } from "../lib/utils";
@@ -97,13 +97,17 @@ export async function importArtWorks(
} else {
const img = file.data;
const pixels = await imageToMural(img, palette);
const x = Math.floor(cords.ux - (img.width / 2));
const y = Math.floor(cords.uy - (img.height / 2));
const fakeMural = new Mural(img.alt, x, y, img.width, img.height, pixels);
const muralExtended = createMuralExtended(fakeMural, palette.hex);
const mural = await new Promise<Mural>((resolve, reject)=> {
store.setOverlayModify({
mural,
muralObj: {
mural: muralExtended,
muralModify: {
name: img.alt,
x: Math.floor(cords.ux - (img.width / 2)),
y: Math.floor(cords.uy - (img.height / 2)),
x,
y,
},
cb: (name, x, y, confirm) => {
if (confirm) {
+1 -1
View File
@@ -22,7 +22,7 @@ export enum StoreEvents {
export interface OverlayReturn {
mural: MuralEx;
muralObj?: Partial<Mural>;
muralModify?: { name: string, x: number, y: number };
cb: (name: string, x: number, y: number, confirm?: boolean) => void;
}