From e6a28635f81e4f12af2c9b9f9c5c38a31ca3468b Mon Sep 17 00:00:00 2001 From: kts of kettek Date: Fri, 16 Feb 2024 12:08:35 -0800 Subject: [PATCH] Implement brush movement interpolation --- frontend/src/types/tools.ts | 57 ++++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 19 deletions(-) diff --git a/frontend/src/types/tools.ts b/frontend/src/types/tools.ts index 86eeb24..5a90cfc 100644 --- a/frontend/src/types/tools.ts +++ b/frontend/src/types/tools.ts @@ -40,12 +40,18 @@ export interface PickerToolContext { } export class BrushTool implements Tool { + private lastX: number + private lastY: number private active: boolean isActive(): boolean { return this.active } pointerDown(ctx: ToolContext & BrushToolContext, ptr: Pointer) { + // Store last for interp. + this.lastX = ptr.x + this.lastY = ptr.y + this.active = true ctx.file.capture() if (ctx.brushSize == 1) { @@ -73,28 +79,41 @@ export class BrushTool implements Tool { } } pointerMove(ctx: ToolContext & BrushToolContext, ptr: Pointer) { - if (ctx.brushSize == 1) { - let p = ctx.file.canvas.getPixel(ptr.x, ptr.y) - if (p !== -1) { - ctx.file.push(new PixelPlaceUndoable(ptr.x, ptr.y, p, ctx.colorIndex)) - } - } else if (ctx.brushSize == 2) { - for (let x1 = 0; x1 < 2; x1++) { - for (let y1 = 0; y1 < 2; y1++) { - let p = ctx.file.canvas.getPixel(ptr.x+x1, ptr.y+y1) - if (p !== -1) { - ctx.file.push(new PixelPlaceUndoable(ptr.x+x1, ptr.y+y1, p, ctx.colorIndex)) + let dx = this.lastX - ptr.x + let dy = this.lastY - ptr.y + this.lastX = ptr.x + this.lastY = ptr.y + + let angle = Math.atan2(dy, dx) + let dist = Math.sqrt(dx*dx + dy*dy) + let steps = Math.ceil(dist) + for (let i = 0; i < steps; i++) { + let x = Math.floor(this.lastX + Math.cos(angle) * i) + let y = Math.floor(this.lastY + Math.sin(angle) * i) + + if (ctx.brushSize == 1) { + let p = ctx.file.canvas.getPixel(x, y) + if (p !== -1) { + ctx.file.push(new PixelPlaceUndoable(x, y, p, ctx.colorIndex)) + } + } else if (ctx.brushSize == 2) { + for (let x1 = 0; x1 < 2; x1++) { + for (let y1 = 0; y1 < 2; y1++) { + let p = ctx.file.canvas.getPixel(x+x1, y+y1) + if (p !== -1) { + ctx.file.push(new PixelPlaceUndoable(x+x1, y+y1, p, ctx.colorIndex)) + } } } + } else { + let shape: PixelPosition[] + if (ctx.brushType == "circle") { + shape = FilledCircle(x, y, ctx.brushSize-2, ctx.colorIndex) + } else if (ctx.brushType == "square") { + shape = FilledSquare(x, y, ctx.brushSize, ctx.colorIndex) + } + ctx.file.push(new PixelsPlaceUndoable(shape)) } - } else { - let shape: PixelPosition[] - if (ctx.brushType == "circle") { - shape = FilledCircle(ptr.x, ptr.y, ctx.brushSize-2, ctx.colorIndex) - } else if (ctx.brushType == "square") { - shape = FilledSquare(ptr.x, ptr.y, ctx.brushSize, ctx.colorIndex) - } - ctx.file.push(new PixelsPlaceUndoable(shape)) } } pointerUp(ctx: ToolContext, ptr: Pointer) {