Implement brush movement interpolation
parent
455a9887ac
commit
e6a28635f8
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue