import { BaseTool } from './base-tool'; import type { PointerState, ToolSettings } from '@/types'; import { distance } from '@/lib/utils'; /** * Eraser tool - Remove pixels */ export class EraserTool extends BaseTool { private lastX = 0; private lastY = 0; constructor() { super('Eraser'); } onPointerDown( pointer: PointerState, ctx: CanvasRenderingContext2D, settings: ToolSettings ): void { this.isDrawing = true; this.lastX = pointer.x; this.lastY = pointer.y; // Erase initial stamp this.eraseStamp(pointer.x, pointer.y, ctx, settings); } onPointerMove( pointer: PointerState, ctx: CanvasRenderingContext2D, settings: ToolSettings ): void { if (!this.isDrawing) return; // Calculate distance from last point const dist = distance(this.lastX, this.lastY, pointer.x, pointer.y); const spacing = settings.size * settings.spacing; if (dist >= spacing) { // Interpolate between points for smooth erasing const steps = Math.ceil(dist / spacing); for (let i = 1; i <= steps; i++) { const t = i / steps; const x = this.lastX + (pointer.x - this.lastX) * t; const y = this.lastY + (pointer.y - this.lastY) * t; this.eraseStamp(x, y, ctx, settings); } this.lastX = pointer.x; this.lastY = pointer.y; } } onPointerUp( pointer: PointerState, ctx: CanvasRenderingContext2D, settings: ToolSettings ): void { this.isDrawing = false; } /** * Erase a circular area */ private eraseStamp( x: number, y: number, ctx: CanvasRenderingContext2D, settings: ToolSettings ): void { ctx.save(); ctx.globalCompositeOperation = 'destination-out'; ctx.globalAlpha = settings.opacity; ctx.beginPath(); ctx.arc(x, y, settings.size / 2, 0, Math.PI * 2); ctx.fill(); ctx.restore(); } }