/** * WebcamManager - Handles webcam integration for photography tasks * Provides camera access, photo capture, and integration with interactive scenarios */ class WebcamManager { constructor(game) { this.game = game; this.stream = null; this.video = null; this.canvas = null; this.context = null; this.isActive = false; this.capturedPhotos = []; this.currentPhotoSession = null; this.preventClose = false; // Prevent camera closure during mirror sessions this.usedPositions = new Set(); // Track positions used in this session to prevent repeats console.log('๐ฅ WebcamManager initialized'); } /** * Initialize webcam functionality */ async init() { console.log('๐ฅ Initializing webcam system...'); // Check if webcam is supported if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) { console.warn('๐ท Webcam not supported in this browser'); return false; } // Create video element for camera feed this.video = document.createElement('video'); this.video.setAttribute('playsinline', true); this.video.style.display = 'none'; document.body.appendChild(this.video); // Create canvas for photo capture this.canvas = document.createElement('canvas'); this.context = this.canvas.getContext('2d'); console.log('โ Webcam system ready'); return true; } /** * Request camera access from user */ async requestCameraAccess() { console.log('๐ท Requesting camera access...'); try { const constraints = { video: { width: { ideal: 1280 }, height: { ideal: 720 }, facingMode: 'user' // Front-facing camera preferred }, audio: false }; this.stream = await navigator.mediaDevices.getUserMedia(constraints); this.video.srcObject = this.stream; return new Promise((resolve) => { this.video.onloadedmetadata = () => { this.video.play(); this.isActive = true; console.log('โ Camera access granted and active'); resolve(true); }; }); } catch (error) { console.error('โ Camera access denied or failed:', error); this.showCameraError(error); return false; } } /** * Start photo session with progress tracking */ async startPhotoSessionWithProgress(sessionType, taskData) { console.log(`๐ธ Starting photo session with progress: ${sessionType}`); // Request camera if not already active if (!this.isActive) { const accessGranted = await this.requestCameraAccess(); if (!accessGranted) return false; } this.currentPhotoSession = { type: sessionType, taskData: taskData, photos: [], startTime: Date.now(), requirements: taskData.requirements || { count: 1, description: 'Take photos to complete' }, photosNeeded: taskData.requirements?.count || 1 }; // Show camera interface with progress this.showCameraInterfaceWithProgress(); return true; } /** * Display camera interface with progress tracking */ showCameraInterfaceWithProgress() { // Create camera overlay const overlay = document.createElement('div'); overlay.id = 'camera-overlay'; overlay.innerHTML = `
${this.currentPhotoSession.requirements.description}
โ ๏ธ Photos are stored locally and not uploaded anywhere
Position yourself according to the task instructions
Photos taken: 0
โ ๏ธ Photos are stored locally and not uploaded anywhere
Would you like to save your captured photos so you can view and download them later?
Photos are stored locally on your device only. You can change this setting anytime in options.
${verificationData?.instructions || 'Follow the position instructions and maintain pose'}
${taskData?.instructions || 'Use the webcam as your mirror'}
Task Failed
โข Status: Task abandoned before completion
โข Reason: Lack of commitment and discipline
โข Result: Complete failure to follow instructions
This training was designed to test your dedication. You failed that test miserably.
If you can't handle basic mirror exercises, maybe you're not ready for real training. Consider whether you actually want to improve yourself or if you're just wasting everyone's time.
Consequence: Session will restart. Try to show some backbone next time.