Implement brush movement interpolation
parent
455a9887ac
commit
e6a28635f8
|
@ -40,12 +40,18 @@ export interface PickerToolContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class BrushTool implements Tool {
|
export class BrushTool implements Tool {
|
||||||
|
private lastX: number
|
||||||
|
private lastY: number
|
||||||
private active: boolean
|
private active: boolean
|
||||||
isActive(): boolean {
|
isActive(): boolean {
|
||||||
return this.active
|
return this.active
|
||||||
}
|
}
|
||||||
|
|
||||||
pointerDown(ctx: ToolContext & BrushToolContext, ptr: Pointer) {
|
pointerDown(ctx: ToolContext & BrushToolContext, ptr: Pointer) {
|
||||||
|
// Store last for interp.
|
||||||
|
this.lastX = ptr.x
|
||||||
|
this.lastY = ptr.y
|
||||||
|
|
||||||
this.active = true
|
this.active = true
|
||||||
ctx.file.capture()
|
ctx.file.capture()
|
||||||
if (ctx.brushSize == 1) {
|
if (ctx.brushSize == 1) {
|
||||||
|
@ -73,28 +79,41 @@ export class BrushTool implements Tool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pointerMove(ctx: ToolContext & BrushToolContext, ptr: Pointer) {
|
pointerMove(ctx: ToolContext & BrushToolContext, ptr: Pointer) {
|
||||||
if (ctx.brushSize == 1) {
|
let dx = this.lastX - ptr.x
|
||||||
let p = ctx.file.canvas.getPixel(ptr.x, ptr.y)
|
let dy = this.lastY - ptr.y
|
||||||
if (p !== -1) {
|
this.lastX = ptr.x
|
||||||
ctx.file.push(new PixelPlaceUndoable(ptr.x, ptr.y, p, ctx.colorIndex))
|
this.lastY = ptr.y
|
||||||
}
|
|
||||||
} else if (ctx.brushSize == 2) {
|
let angle = Math.atan2(dy, dx)
|
||||||
for (let x1 = 0; x1 < 2; x1++) {
|
let dist = Math.sqrt(dx*dx + dy*dy)
|
||||||
for (let y1 = 0; y1 < 2; y1++) {
|
let steps = Math.ceil(dist)
|
||||||
let p = ctx.file.canvas.getPixel(ptr.x+x1, ptr.y+y1)
|
for (let i = 0; i < steps; i++) {
|
||||||
if (p !== -1) {
|
let x = Math.floor(this.lastX + Math.cos(angle) * i)
|
||||||
ctx.file.push(new PixelPlaceUndoable(ptr.x+x1, ptr.y+y1, p, ctx.colorIndex))
|
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) {
|
pointerUp(ctx: ToolContext, ptr: Pointer) {
|
||||||
|
|
Loading…
Reference in New Issue