// const URL = "https://teachablemachine.withgoogle.com/models/uYk-wIQy6/"; const URL = "https://teachablemachine.withgoogle.com/models/DTgj24KYa/"; let model, webcam, ctx, labelContainer, maxPredictions; let isInitialized = false; // Wait for libraries to load function waitForLibraries() { return new Promise((resolve) => { const checkLibraries = () => { if (typeof tmPose !== 'undefined' && typeof tf !== 'undefined') { resolve(); } else { setTimeout(checkLibraries, 100); } }; checkLibraries(); }); } async function init() { if (isInitialized) return; // First, wait for libraries to load await waitForLibraries(); const startBtn = document.getElementById('startBtn'); const statusIndicator = document.getElementById('statusIndicator'); const loadingSpinner = document.getElementById('loadingSpinner'); // Display loading status startBtn.innerHTML = '🔄 Loading...'; startBtn.disabled = true; loadingSpinner.style.display = 'block'; try { const modelURL = URL + "model.json"; const metadataURL = URL + "metadata.json"; model = await tmPose.load(modelURL, metadataURL); maxPredictions = model.getTotalClasses(); const size = 300; const flip = true; webcam = new tmPose.Webcam(size, size, flip); await webcam.setup(); await webcam.play(); window.requestAnimationFrame(loop); const canvas = document.getElementById("canvas"); canvas.width = size; canvas.height = size; ctx = canvas.getContext("2d"); labelContainer = document.getElementById("label-container"); labelContainer.innerHTML = ''; for (let i = 0; i < maxPredictions; i++) { const div = document.createElement("div"); div.className = "prediction-item"; div.innerHTML = '
Loading...
'; labelContainer.appendChild(div); } // Update UI status startBtn.innerHTML = '✅ Detecting...'; statusIndicator.classList.add('active'); loadingSpinner.style.display = 'none'; isInitialized = true; } catch (error) { console.error('Initialization failed:', error); startBtn.innerHTML = '❌ Load Failed, Retry'; startBtn.disabled = false; loadingSpinner.style.display = 'none'; } } async function loop(timestamp) { if (webcam) { webcam.update(); await predict(); window.requestAnimationFrame(loop); } } async function predict() { try { const { pose, posenetOutput } = await model.estimatePose(webcam.canvas); const prediction = await model.predict(posenetOutput); for (let i = 0; i < maxPredictions; i++) { const probability = (prediction[i].probability * 100).toFixed(1); const className = prediction[i].className; // Add emojis and better formatting let emoji = '🏀'; if (probability > 80) emoji = '🔥'; else if (probability > 60) emoji = '⭐'; else if (probability > 40) emoji = '👍'; const predictionText = `${emoji} ${className}: ${probability}%`; const predictionElement = labelContainer.childNodes[i]; if (predictionElement) { predictionElement.querySelector('.prediction-text').innerHTML = predictionText; // Add dynamic styling const confidence = parseFloat(probability); if (confidence > 50) { predictionElement.style.borderLeftColor = '#44ff44'; predictionElement.style.background = 'rgba(68, 255, 68, 0.1)'; } else if (confidence > 30) { predictionElement.style.borderLeftColor = '#ffd700'; predictionElement.style.background = 'rgba(255, 215, 0, 0.1)'; } else { predictionElement.style.borderLeftColor = '#ff6b35'; predictionElement.style.background = 'rgba(255, 107, 53, 0.1)'; } } } drawPose(pose); } catch (error) { console.error('Prediction error:', error); } } function drawPose(pose) { if (webcam && webcam.canvas && ctx) { ctx.drawImage(webcam.canvas, 0, 0); if (pose) { const minPartConfidence = 0.5; tmPose.drawKeypoints(pose.keypoints, minPartConfidence, ctx); tmPose.drawSkeleton(pose.keypoints, minPartConfidence, ctx); } } } // Check if libraries are loaded after page load window.addEventListener('load', async function() { try { await waitForLibraries(); console.log('🏀 NBA Pose Detector Ready!'); // Display ready status const startBtn = document.getElementById('startBtn'); startBtn.innerHTML = '🚀 Start Detection'; startBtn.style.opacity = '1'; } catch (error) { console.error('Library load failed:', error); const startBtn = document.getElementById('startBtn'); startBtn.innerHTML = '❌ Load Failed'; startBtn.disabled = true; } });