/** * Screen Capture Tool * Captures a screenshot from the user's screen using the Screen Capture API * * @module ScreenCapture */ (function() { console.log('Starting Screen Capture Tool initialization...'); window.captureScreenshot = async function() { console.log('captureScreenshot called'); try { // Request screen capture from user const mediaStream = await navigator.mediaDevices.getDisplayMedia({ video: { mediaSource: 'screen' } }); // Create video element to capture frame const video = document.createElement('video'); video.srcObject = mediaStream; return new Promise((resolve) => { video.onloadedmetadata = () => { // Create canvas and draw video frame const canvas = document.createElement('canvas'); canvas.width = video.videoWidth; canvas.height = video.videoHeight; const ctx = canvas.getContext('2d'); ctx.drawImage(video, 0, 0); // Stop all media tracks mediaStream.getTracks().forEach(track => track.stop()); // Return canvas for further processing resolve(canvas); }; video.play(); }); } catch (error) { console.error('Screenshot capture failed:', error); return null; } }; window.captureSnip = async function() { console.log('captureSnip called'); try { // First, get the full screen capture const mediaStream = await navigator.mediaDevices.getDisplayMedia({ video: { mediaSource: 'screen' } }); // Create video element to capture frame const video = document.createElement('video'); video.srcObject = mediaStream; return new Promise((resolve) => { video.onloadedmetadata = () => { // Capture full screen to canvas const fullCanvas = document.createElement('canvas'); fullCanvas.width = video.videoWidth; fullCanvas.height = video.videoHeight; const fullCtx = fullCanvas.getContext('2d'); fullCtx.drawImage(video, 0, 0); // Stop video tracks mediaStream.getTracks().forEach(track => track.stop()); // Show selection overlay createSelectionOverlay(fullCanvas, resolve); }; video.play(); }); } catch (error) { console.error('Snip capture failed:', error); return null; } }; function createSelectionOverlay(fullCanvas, resolve) { console.log('createSelectionOverlay called'); // Create overlay container const overlay = document.createElement('div'); overlay.style.cssText = ` position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; background: rgba(0, 0, 0, 0.3); cursor: crosshair; z-index: 99999; user-select: none; `; // Create canvas for drawing selection box const selectionCanvas = document.createElement('canvas'); selectionCanvas.style.cssText = ` position: fixed; top: 0; left: 0; cursor: crosshair; z-index: 100000; `; selectionCanvas.width = window.innerWidth; selectionCanvas.height = window.innerHeight; // Scale factor for mapping screen pixels to window pixels const scaleX = fullCanvas.width / window.innerWidth; const scaleY = fullCanvas.height / window.innerHeight; let isDrawing = false; let startX = 0; let startY = 0; let endX = 0; let endY = 0; const ctx = selectionCanvas.getContext('2d'); function drawSelection() { ctx.clearRect(0, 0, selectionCanvas.width, selectionCanvas.height); if (!isDrawing && (startX === endX && startY === endY)) { return; } const x = Math.min(startX, endX); const y = Math.min(startY, endY); const width = Math.abs(endX - startX); const height = Math.abs(endY - startY); // Draw selection rectangle ctx.strokeStyle = '#0EA5E9'; ctx.lineWidth = 2; ctx.strokeRect(x, y, width, height); // Fill with semi-transparent color ctx.fillStyle = 'rgba(14, 165, 233, 0.1)'; ctx.fillRect(x, y, width, height); // Draw corner handles const handleSize = 8; ctx.fillStyle = '#0EA5E9'; ctx.fillRect(x - handleSize / 2, y - handleSize / 2, handleSize, handleSize); ctx.fillRect(x + width - handleSize / 2, y - handleSize / 2, handleSize, handleSize); ctx.fillRect(x - handleSize / 2, y + height - handleSize / 2, handleSize, handleSize); ctx.fillRect(x + width - handleSize / 2, y + height - handleSize / 2, handleSize, handleSize); } selectionCanvas.addEventListener('mousedown', (e) => { isDrawing = true; startX = e.clientX; startY = e.clientY; endX = startX; endY = startY; }); selectionCanvas.addEventListener('mousemove', (e) => { if (isDrawing) { endX = e.clientX; endY = e.clientY; drawSelection(); } }); selectionCanvas.addEventListener('mouseup', () => { if (isDrawing) { isDrawing = false; const x = Math.min(startX, endX); const y = Math.min(startY, endY); const width = Math.abs(endX - startX); const height = Math.abs(endY - startY); // Validate selection if (width < 10 || height < 10) { console.warn('Selection too small'); cleanup(); resolve(null); return; } // Create cropped canvas from full screenshot const croppedCanvas = document.createElement('canvas'); croppedCanvas.width = width * scaleX; croppedCanvas.height = height * scaleY; const croppedCtx = croppedCanvas.getContext('2d'); // Draw cropped section from full canvas croppedCtx.drawImage( fullCanvas, x * scaleX, y * scaleY, width * scaleX, height * scaleY, 0, 0, width * scaleX, height * scaleY ); cleanup(); resolve(croppedCanvas); } }); // Handle escape key const handleKeydown = (e) => { if (e.key === 'Escape') { cleanup(); resolve(null); } }; function cleanup() { document.removeEventListener('keydown', handleKeydown); overlay.remove(); selectionCanvas.remove(); } document.addEventListener('keydown', handleKeydown); document.body.appendChild(overlay); document.body.appendChild(selectionCanvas); console.log('Snipping tool active: Draw a rectangle to select area. Press ESC to cancel.'); } window.canvasToFile = async function(canvas, filename = null) { console.log('canvasToFile called'); return new Promise((resolve) => { const name = filename || `screenshot-${Date.now()}.png`; canvas.toBlob((blob) => { const file = new File([blob], name, { type: 'image/png' }); resolve(file); }); }); }; console.log('✓ Screen Capture Tool loaded successfully'); console.log('Functions available: window.captureScreenshot, window.captureSnip, window.canvasToFile'); })();