class CanvasManager { constructor(canvas, ctx) { this.canvas = canvas; this.ctx = ctx; this.gridSize = 20; this.showGrid = true; this.showMeasurements = true; } // Grid drawing drawGrid() { this.ctx.strokeStyle = '#e0e0e0'; this.ctx.lineWidth = 1; this.ctx.setLineDash([1, 4]); // Vertical lines for (let x = 0; x <= this.canvas.width; x += this.gridSize) { this.ctx.beginPath(); this.ctx.moveTo(x, 0); this.ctx.lineTo(x, this.canvas.height); this.ctx.stroke(); } // Horizontal lines for (let y = 0; y <= this.canvas.height; y += this.gridSize) { this.ctx.beginPath(); this.ctx.moveTo(0, y); this.ctx.lineTo(this.canvas.width, y); this.ctx.stroke(); } this.ctx.setLineDash([]); } // Snap to grid functionality snapToGridPoint(value) { return Math.round(value / this.gridSize) * this.gridSize; } // Clear canvas clearCanvas() { this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); this.ctx.setLineDash([]); } // Save and restore context state saveContext() { this.ctx.save(); } restoreContext() { this.ctx.restore(); } // Apply transformations applyTransformations(panX, panY, zoomLevel) { this.ctx.translate(panX, panY); this.ctx.scale(zoomLevel, zoomLevel); } // Draw preview with dashed lines drawPreview(startX, startY, endX, endY, color = '#667eea') { this.ctx.strokeStyle = color; this.ctx.lineWidth = 2; this.ctx.setLineDash([5, 5]); this.ctx.beginPath(); this.ctx.moveTo(startX, startY); this.ctx.lineTo(endX, endY); this.ctx.stroke(); this.ctx.setLineDash([]); } // Draw measurement text drawMeasurement(startX, startY, endX, endY, text) { const midX = (startX + endX) / 2; const midY = (startY + endY) / 2; this.ctx.fillStyle = '#333'; this.ctx.font = '12px Arial'; this.ctx.textAlign = 'center'; this.ctx.fillText(text, midX, midY - 10); } // Draw highlight for selected element drawHighlight(element) { this.ctx.strokeStyle = '#ff6b6b'; this.ctx.lineWidth = 3; this.ctx.setLineDash([10, 5]); if (element.type === 'room') { this.ctx.strokeRect(element.startX, element.startY, element.endX - element.startX, element.endY - element.startY); } else if (element.type === 'wall') { this.ctx.beginPath(); this.ctx.moveTo(element.startX, element.startY); this.ctx.lineTo(element.endX, element.endY); this.ctx.stroke(); } this.ctx.setLineDash([]); } // Resize canvas to fit container resizeCanvas() { const container = this.canvas.parentElement; this.canvas.width = container.clientWidth; this.canvas.height = container.clientHeight; } // Update grid status display updateGridStatus() { const gridStatus = document.getElementById('gridStatus'); if (gridStatus) { gridStatus.textContent = this.showGrid ? 'ON' : 'OFF'; gridStatus.className = this.showGrid ? 'font-medium text-green-600' : 'font-medium text-red-600'; } } }