document.addEventListener('DOMContentLoaded', function() { // Initialize empty results array const scanResults = []; // Camera and storage access variables let cameraStream = null; let isCameraActive = false; const cameraVideo = document.getElementById('cameraStream'); const captureCanvas = document.getElementById('captureCanvas'); const placeholderImage = document.getElementById('placeholderImage'); const uploadButton = document.getElementById('uploadButton'); const captureButton = document.getElementById('captureButton'); const textPreview = document.querySelector('.text-preview'); // Tab switching functionality const tabButtons = document.querySelectorAll('.tab-button'); const tabContents = document.querySelectorAll('.tab-content'); // Initialize tabs - show home tab by default document.getElementById('home').classList.add('active'); tabButtons.forEach(button => { button.addEventListener('click', function(e) { e.preventDefault(); const tabId = this.getAttribute('data-tab'); // Remove active class from all tabs and buttons tabButtons.forEach(btn => btn.classList.remove('active')); tabContents.forEach(content => content.classList.remove('active')); // Add active class to clicked tab and button this.classList.add('active'); document.getElementById(tabId).classList.add('active'); // Stop camera when leaving home tab if (tabId !== 'home') { stopCamera(); } }); }); // Initialize the first tab as active const initialTab = document.querySelector('.tab-button[data-tab="home"]'); if (initialTab) { initialTab.classList.add('active'); } // Request camera permission and initialize camera async function initializeCamera() { try { // Stop any existing camera stream stopCamera(); // Try environment camera first, then user camera, then any camera const constraints = [ { video: { facingMode: 'environment' } }, { video: { facingMode: 'user' } }, { video: true } ]; let stream = null; for (const constraint of constraints) { try { stream = await navigator.mediaDevices.getUserMedia(constraint); break; } catch (err) { console.warn(`Camera constraint failed:`, constraint, err); continue; } } if (!stream) { throw new Error('No camera available'); } cameraStream = stream; cameraVideo.srcObject = stream; isCameraActive = true; // Wait for video to load metadata await new Promise((resolve) => { cameraVideo.onloadedmetadata = resolve; }); return true; } catch (error) { console.error('Error accessing camera:', error); alert('Camera access is required for capturing images. Please allow camera permissions and ensure a camera is connected.'); isCameraActive = false; return false; } } // Stop camera stream function stopCamera() { if (cameraStream) { const tracks = cameraStream.getTracks(); tracks.forEach(track => { track.stop(); }); cameraStream = null; } isCameraActive = false; cameraVideo.style.display = 'none'; placeholderImage.style.display = 'block'; } // Capture image from camera async function captureImage() { // Ensure camera is initialized if (!isCameraActive) { const initialized = await initializeCamera(); if (!initialized) { alert('Failed to access camera. Please check permissions.'); return; } } try { // Show camera stream and hide placeholder placeholderImage.style.display = 'none'; cameraVideo.style.display = 'block'; // Small delay to let camera stabilize await new Promise(resolve => setTimeout(resolve, 200)); // Set canvas dimensions to match video captureCanvas.width = cameraVideo.videoWidth || 640; captureCanvas.height = cameraVideo.videoHeight || 480; const context = captureCanvas.getContext('2d'); // Draw video frame to canvas context.drawImage(cameraVideo, 0, 0, captureCanvas.width, captureCanvas.height); // Get image data URL const imageData = captureCanvas.toDataURL('image/jpeg', 0.8); // Process the captured image processCapturedImage(imageData); // Stop camera after capture stopCamera(); } catch (error) { console.error('Error capturing image:', error); alert('Failed to capture image. Please try again.'); stopCamera(); } } // Process captured image and show results function processCapturedImage(imageData) { // Show image preview const imagePreviewContainer = document.querySelector('.image-preview-container'); const previewImage = document.getElementById('preview-image'); previewImage.src = imageData; imagePreviewContainer.style.display = 'block'; // Store and simulate OCR results with sample data const result = { type: 'scan', content: 'The quick brown fox jumps over the lazy dog\n1234567890', confidence: '98.7%', timestamp: new Date().toISOString(), imageData: imageData }; scanResults.push(result); // Show results with image preview and processed text textPreview.innerHTML = `
The quick brown fox jumps over the lazy dog
1234567890
Processing image...
Invoice #INV-2023-0456
Client: Acme Corporation
Total: $1,245.00
Due Date: 12/15/2023