From 4a43fe0dc224c0167d1c51080e350dff6159fada Mon Sep 17 00:00:00 2001 From: Devin Elrose Date: Tue, 2 Jan 2024 21:32:18 -0800 Subject: [PATCH] well, it was an attempt --- apps/web/src/main.ts | 6 +- .../src/engine/CanvasHistory.ts | 11 +- .../src/engine/DrawingEngine.ts | 27 ----- .../src/engine/QueuedDrawingEngine.ts | 104 ++++++++++++++++++ libs/drawing-engine/src/exports.ts | 1 + 5 files changed, 115 insertions(+), 34 deletions(-) create mode 100644 libs/drawing-engine/src/engine/QueuedDrawingEngine.ts diff --git a/apps/web/src/main.ts b/apps/web/src/main.ts index 7ab57dd..29d30c5 100644 --- a/apps/web/src/main.ts +++ b/apps/web/src/main.ts @@ -1,6 +1,6 @@ import "./style.css" -import { WebDrawingEngine, EventType, ToolNames, ToolName } from "@libs/drawing-engine" +import { QueuedDrawingEngine, EventType, ToolNames, ToolName } from "@libs/drawing-engine" import { ColorPicker } from "@libs/color-picker" import { Color } from "@libs/shared" @@ -17,7 +17,7 @@ function main() { } const width = Math.min(window.innerWidth, 500) const height = Math.min(window.innerHeight, 500) - const engine = new WebDrawingEngine(canvasRoot, { + const engine = new QueuedDrawingEngine(canvasRoot, { width, height, pixelDensity: window.devicePixelRatio, @@ -112,7 +112,7 @@ function makeToolbar( onUndo: () => void onRedo: () => void - addListener: WebDrawingEngine["addListener"] + addListener: QueuedDrawingEngine["addListener"] }, ) { const localState = { diff --git a/libs/drawing-engine/src/engine/CanvasHistory.ts b/libs/drawing-engine/src/engine/CanvasHistory.ts index 2493790..64e51b7 100644 --- a/libs/drawing-engine/src/engine/CanvasHistory.ts +++ b/libs/drawing-engine/src/engine/CanvasHistory.ts @@ -84,7 +84,6 @@ export class CanvasHistory { protected currentEntry: HistoryEntry | null = null protected redoStack: Array = [] protected hasTruncated = false - private queue: CallbackQueue = new CallbackQueue() private constructor( protected readonly engine: DrawingEngine, @@ -280,7 +279,11 @@ export class CanvasHistory { this.engine._clear() if (!hasClear && blobId) { const blob = await this.db.blobs.get(blobId) - await this.drawBlob(blob) + if (!blob) { + console.warn("Could not get blob") + } else { + await this.drawBlob(blob) + } } await this.drawActions(filteredActions) @@ -316,10 +319,10 @@ export class CanvasHistory { } protected drawBlob(blob: Blob): Promise { + const image = new Image() if (!blob) { - return Promise.reject(new Error("No blob")) + return Promise.resolve(image) } - const image = new Image() image.src = URL.createObjectURL(blob) return new Promise((resolve, reject) => { diff --git a/libs/drawing-engine/src/engine/DrawingEngine.ts b/libs/drawing-engine/src/engine/DrawingEngine.ts index cbc9e5b..0180046 100644 --- a/libs/drawing-engine/src/engine/DrawingEngine.ts +++ b/libs/drawing-engine/src/engine/DrawingEngine.ts @@ -91,7 +91,6 @@ export class DrawingEngine { } private listeners: Partial = {} - protected history: CanvasHistory | null = null constructor( public gl: WebGLRenderingContext, @@ -107,14 +106,6 @@ export class DrawingEngine { prevTool: defaultTool, } - CanvasHistory.create(this, { - maxHistory: 10, - actionsPerHistory: 10, - }).then((history) => { - this.history = history - this.checkLoaded() - }) - this.savedDrawingLayer = this.makeLayer() this.activeDrawingLayer = this.makeLayer({ clearBeforeDrawing: true }) @@ -137,16 +128,6 @@ export class DrawingEngine { return this.gl.canvas } - public isLoaded() { - return this.history !== null - } - - private checkLoaded() { - if (this.isLoaded()) { - this.callListeners(EventType.engineLoaded, undefined) - } - } - private makeLayer(options?: Partial) { return new Layer(this.gl, options) } @@ -315,12 +296,4 @@ export class DrawingEngine { this.savedDrawingLayer = copy this.render("draw") } - - public undo() { - return this.history?.undo() - } - - public redo() { - return this.history?.redo() - } } diff --git a/libs/drawing-engine/src/engine/QueuedDrawingEngine.ts b/libs/drawing-engine/src/engine/QueuedDrawingEngine.ts new file mode 100644 index 0000000..e535b05 --- /dev/null +++ b/libs/drawing-engine/src/engine/QueuedDrawingEngine.ts @@ -0,0 +1,104 @@ +import { Color } from "@libs/shared" +import { CallbackQueue } from "./CallbackQueue" +import { DrawingEngineOptions, DrawingEventHandler, EventType } from "./DrawingEngine" +import { WebDrawingEngine } from "./WebDrawingEngine" +import { ToolName } from "../exports" +import { SourceImage } from "../utils/image/SourceImage" +import { CanvasHistory } from "./CanvasHistory" + +type IDrawingEngine = Pick< + WebDrawingEngine, + | "getCurrentColor" + | "getOpacity" + | "activeTool" + | "clearCanvas" + | "setOpacity" + | "tools" + | "setColor" + | "setTool" + | "loadImage" + | "getDataUri" + | "getCurrentToolName" +> + +export class QueuedDrawingEngine implements IDrawingEngine { + private queue = new CallbackQueue() + private engine: WebDrawingEngine + private history: CanvasHistory | null = null + + constructor(root: HTMLElement, options: DrawingEngineOptions) { + this.engine = new WebDrawingEngine(root, options) + + this.enqueue(() => this.setupHistory()) + this.enqueue(() => this.engine.callListeners(EventType.engineLoaded, undefined)) + } + + private async setupHistory() { + this.history = await CanvasHistory.create(this.engine, { + maxHistory: 10, + actionsPerHistory: 10, + }) + } + + public addListener(eventName: E, cb: DrawingEventHandler) { + this.engine.addListener(eventName, cb) + return this + } + + private enqueue(cb: () => void | Promise) { + // this.queue.push(cb) + cb() + } + + public setTool(tool: ToolName) { + this.enqueue(() => this.engine.setTool(tool)) + } + + public setOpacity(opacity: number) { + this.enqueue(() => this.engine.setOpacity(opacity)) + } + + public setColor(color: Color) { + this.enqueue(() => this.engine.setColor(color)) + } + + public loadImage(image: SourceImage) { + this.enqueue(() => this.engine.loadImage(image)) + } + + public undo() { + this.enqueue(() => this.history?.undo()) + } + + public redo() { + this.enqueue(() => this.history?.redo()) + } + + public clearCanvas() { + this.enqueue(() => this.engine.clearCanvas()) + } + + public getDataUri() { + return this.engine.getDataUri() + } + + public getCurrentColor() { + return this.engine.getCurrentColor() + } + + public getOpacity() { + return this.engine.getOpacity() + } + + public getCurrentToolName(): ToolName { + return this.engine.getCurrentToolName() + } + + public get tools() { + return this.engine.tools + } + + public get activeTool() { + return this.engine.activeTool + } +} diff --git a/libs/drawing-engine/src/exports.ts b/libs/drawing-engine/src/exports.ts index 1a53256..a346c2e 100644 --- a/libs/drawing-engine/src/exports.ts +++ b/libs/drawing-engine/src/exports.ts @@ -2,3 +2,4 @@ export * from "./engine/WebDrawingEngine" export { EventType } from "./engine/DrawingEngine" export type { ToolName } from "./tools/Tools" export { ToolNames } from "./tools/Tools" +export { QueuedDrawingEngine } from "./engine/QueuedDrawingEngine"