class ZoomPanManager { constructor(canvasManager) { this.canvasManager = canvasManager; this.canvas = canvasManager.canvas; this.zoomLevel = 1.0; this.minZoom = 0.1; this.maxZoom = 5.0; this.zoomStep = 0.1; this.panX = 0; this.panY = 0; this.isPanning = false; this.lastPanX = 0; this.lastPanY = 0; } // Zoom in zoomIn() { this.zoomLevel = Math.min(this.zoomLevel + this.zoomStep, this.maxZoom); this.updateZoomLevel(); } // Zoom out zoomOut() { this.zoomLevel = Math.max(this.zoomLevel - this.zoomStep, this.minZoom); this.updateZoomLevel(); } // Reset zoom and pan resetZoom() { this.zoomLevel = 1.0; this.panX = 0; this.panY = 0; this.updateZoomLevel(); } // Pan the view pan(deltaX, deltaY) { this.panX += deltaX; this.panY += deltaY; } // Update zoom level display updateZoomLevel() { const zoomLevelElement = document.getElementById('zoomLevel'); if (zoomLevelElement) { zoomLevelElement.textContent = Math.round(this.zoomLevel * 100) + '%'; } } // Handle mouse wheel for zoom handleWheel(e) { e.preventDefault(); const delta = e.deltaY > 0 ? -this.zoomStep : this.zoomStep; const newZoom = Math.max(this.minZoom, Math.min(this.maxZoom, this.zoomLevel + delta)); if (newZoom !== this.zoomLevel) { this.zoomLevel = newZoom; this.updateZoomLevel(); } } // Handle mouse down for panning handleMouseDown(e) { // Check if middle mouse button or Ctrl+click for panning if (e.button === 1 || (e.button === 0 && e.ctrlKey)) { e.preventDefault(); this.isPanning = true; this.lastPanX = e.clientX; this.lastPanY = e.clientY; this.canvas.style.cursor = 'grabbing'; } } // Handle mouse move for panning handleMouseMove(e) { if (this.isPanning) { const deltaX = e.clientX - this.lastPanX; const deltaY = e.clientY - this.lastPanY; this.panX += deltaX; this.panY += deltaY; this.lastPanX = e.clientX; this.lastPanY = e.clientY; } } // Handle mouse up for panning handleMouseUp(e) { if (this.isPanning) { this.isPanning = false; this.canvas.style.cursor = 'crosshair'; } } // Convert screen coordinates to world coordinates screenToWorld(screenX, screenY) { return { x: (screenX - this.panX) / this.zoomLevel, y: (screenY - this.panY) / this.zoomLevel }; } // Convert world coordinates to screen coordinates worldToScreen(worldX, worldY) { return { x: worldX * this.zoomLevel + this.panX, y: worldY * this.zoomLevel + this.panY }; } // Apply transformations to canvas context applyTransformations() { this.canvasManager.saveContext(); this.canvasManager.applyTransformations(this.panX, this.panY, this.zoomLevel); } // Restore canvas context restoreTransformations() { this.canvasManager.restoreContext(); } // Get current zoom level getZoomLevel() { return this.zoomLevel; } // Get current pan values getPanValues() { return { panX: this.panX, panY: this.panY }; } // Set zoom level setZoomLevel(level) { this.zoomLevel = Math.max(this.minZoom, Math.min(this.maxZoom, level)); this.updateZoomLevel(); } // Set pan values setPanValues(panX, panY) { this.panX = panX; this.panY = panY; } }