Implement brush movement interpolation

main
kts of kettek 2024-02-16 12:08:35 -08:00
parent 455a9887ac
commit e6a28635f8
1 changed files with 38 additions and 19 deletions

View File

@ -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) {