CoolFace
Apppublic

threexlone/snap-sizzle

sourceHugging Faceupdated 11mo agoView on Hugging Face
0likes
script.js322 linesDownload Raw Back to root
1document.addEventListener('DOMContentLoaded', () => {2    // DOM Elements3    const video = document.getElementById('video');4    const canvas = document.getElementById('canvas');5    const captureBtn = document.getElementById('capture-btn');6    const uploadBtn = document.getElementById('upload-btn');7    const fileInput = document.getElementById('file-input');8    const ingredientsList = document.getElementById('ingredients-list');9    const recipesSection = document.getElementById('recipes-section');10    const recipesContainer = document.getElementById('recipes-container');11    const cameraView = document.getElementById('camera-view');12    // Camera setup13    let stream = null;14    let isCameraOn = false;15 16    // Toggle camera on camera view click17    cameraView.addEventListener('click', async () => {18        if (isCameraOn) {19            stopCamera();20        } else {21            await startCamera();22        }23    });24 25    // Capture button click handler26    captureBtn.addEventListener('click', async () => {27        if (!isCameraOn) {28            try {29                await startCamera();30                return; // Let user try capturing again31            } catch (err) {32                console.error("Camera failed to start:", err);33                return;34            }35        }36        37        captureImage();38    });39 40    // Upload button click handler41    uploadBtn.addEventListener('click', () => {42        fileInput.click();43    });44    async function startCamera() {45        isCameraOn = true;46        try {47stream = await navigator.mediaDevices.getUserMedia({ video: true });48            video.srcObject = stream;49            video.classList.remove('hidden');50            cameraView.classList.add('hidden');51            captureBtn.disabled = false;52        } catch (err) {53            console.error("Error accessing camera:", err);54            alert("Could not access the camera. Please check permissions.");55        }56    }57    function stopCamera() {58        isCameraOn = false;59        if (stream) {60stream.getTracks().forEach(track => track.stop());61            stream = null;62        }63        video.classList.add('hidden');64        cameraView.classList.remove('hidden');65        captureBtn.disabled = true;66    }67    // Handle file input change68    fileInput.addEventListener('change', (e) => {69        if (e.target.files && e.target.files[0]) {70            const reader = new FileReader();71            reader.onload = async (event) => {72                // Stop camera if running73                if (isCameraOn) {74                    stopCamera();75                }76                77                // Show uploaded image78                cameraView.innerHTML = `<img src="${event.target.result}" class="w-full h-full object-cover rounded">`;79                80                // Detect ingredients from image81                await detectIngredientsFromImage();82            };83            reader.readAsDataURL(e.target.files[0]);84        }85    });86 87    // Capture image function88    function captureImage() {89        if (!stream) return;90        91        canvas.width = video.videoWidth;92        canvas.height = video.videoHeight;93        const ctx = canvas.getContext('2d');94        ctx.drawImage(video, 0, 0, canvas.width, canvas.height);95        96        // Show captured image97        cameraView.innerHTML = '';98        cameraView.appendChild(canvas);99        video.classList.add('hidden');100        cameraView.classList.remove('hidden');101        102        // Detect ingredients103        simulateIngredientDetection();104    }105// Simulate ingredient detection (for demo purposes)106    function simulateIngredientDetection() {107        ingredientsList.innerHTML = '<div class="animate-pulse flex space-x-4"><div class="flex-1 space-y-4 py-1"><div class="h-4 bg-gray-200 rounded w-3/4"></div><div class="space-y-2"><div class="h-4 bg-gray-200 rounded"></div><div class="h-4 bg-gray-200 rounded w-5/6"></div></div></div></div>';108        109        // Simulate API delay110        setTimeout(() => {111            // Demo ingredients112            const demoIngredients = [113                'chicken breast',114                'bell pepper',115                'onion',116                'garlic',117                'olive oil',118                'salt',119                'black pepper'120            ];121            displayIngredients(demoIngredients);122            const recipes = await findRecipes(demoIngredients);123            displayRecipes(recipes);124}, 1500);125    }126 127    // Detect ingredients from image (simulated for demo)128    async function detectIngredientsFromImage() {129        try {130            simulateIngredientDetection();131        } catch (error) {132console.error('Error detecting ingredients:', error);133            ingredientsList.innerHTML = `134                <div class="text-center p-4">135                    <i data-feather="alert-circle" class="w-12 h-12 text-red-500 mx-auto mb-2"></i>136                    <h4 class="text-lg font-medium text-dark mb-1">Detection Failed</h4>137                    <p class="text-gray-600 mb-4">We couldn't identify ingredients from your photo.</p>138                    <div class="text-sm text-gray-500">139                        <p class="mb-1">• Try taking a clearer photo with good lighting</p>140                        <p class="mb-1">• Make sure ingredients are visible and not overlapping</p>141                        <p>• Try cropping to focus on specific ingredients</p>142                    </div>143                </div>144            `;145            feather.replace();146}147    }148    // Display detected ingredients149    function displayIngredients(ingredients) {150ingredientsList.innerHTML = '';151        ingredients.forEach(ingredient => {152            const tag = document.createElement('span');153            tag.className = 'ingredient-tag';154            tag.innerHTML = `<i data-feather="check-circle" class="w-3 h-3 mr-1"></i> ${ingredient}`;155            ingredientsList.appendChild(tag);156        });157        feather.replace();158    }159    // Find recipes based on ingredients (simulated for demo)160    // Find recipes based on ingredients (simulated for demo)161    async function findRecipes(ingredients) {162        // Show loading state163        recipesSection.classList.remove('hidden');164        recipesContainer.innerHTML = `165<div class="col-span-3 flex flex-col items-center justify-center py-12">166                <div class="animate-spin rounded-full h-12 w-12 border-t-2 border-b-2 border-primary mb-4"></div>167                <p class="text-gray-600">Finding delicious recipes...</p>168            </div>169        `;170        return new Promise((resolve) => {171            setTimeout(() => {172                // Demo recipes data173                const demoRecipes = [174                    {175                        label: "Chicken Stir Fry",176                        image: "http://static.photos/food/640x360/1",177                        totalTime: 30,178                        calories: 450,179                        yield: 2,180                        ingredientLines: [181                            "2 chicken breasts",182                            "1 bell pepper", 183                            "1 onion",184                            "2 cloves garlic",185                            "2 tbsp olive oil"186                        ],187                        url: "#"188                    },189                    {190                        label: "Grilled Chicken Salad",191                        image: "http://static.photos/food/640x360/2",192                        totalTime: 25,193                        calories: 320,194                        yield: 2,195                        ingredientLines: [196                            "2 chicken breasts",197                            "mixed greens",198                            "1 bell pepper",199                            "1/2 onion",200                            "olive oil dressing"201                        ],202                        url: "#"203                    },204                    {205                        label: "Chicken Fajitas",206                        image: "http://static.photos/food/640x360/3",207                        totalTime: 40,208                        calories: 520,209                        yield: 4,210                        ingredientLines: [211                            "2 chicken breasts",212                            "2 bell peppers",213                            "1 onion",214                            "fajita seasoning",215                            "tortillas"216                        ],217                        url: "#"218                    }219                ];220                resolve(demoRecipes);221            }, 1500);222        });223setTimeout(() => {224            // Demo recipes225            const demoRecipes = [226                {227                    label: "Chicken Stir Fry",228                    image: "http://static.photos/food/640x360/1",229                    totalTime: 30,230                    calories: 450,231                    yield: 2,232                    ingredientLines: [233                        "2 chicken breasts",234                        "1 bell pepper",235                        "1 onion",236                        "2 cloves garlic",237                        "2 tbsp olive oil"238                    ],239                    url: "#"240                },241                {242                    label: "Grilled Chicken Salad",243                    image: "http://static.photos/food/640x360/2",244                    totalTime: 25,245                    calories: 320,246                    yield: 2,247                    ingredientLines: [248                        "2 chicken breasts",249                        "mixed greens",250                        "1 bell pepper",251                        "1/2 onion",252                        "olive oil dressing"253                    ],254                    url: "#"255                },256                {257                    label: "Chicken Fajitas",258                    image: "http://static.photos/food/640x360/3",259                    totalTime: 40,260                    calories: 520,261                    yield: 4,262                    ingredientLines: [263                        "2 chicken breasts",264                        "2 bell peppers",265                        "1 onion",266                        "fajita seasoning",267                        "tortillas"268                    ],269                    url: "#"270                }271            ];272        try {273            const recipes = await findRecipes(ingredients);274            275            // Clear previous results276            recipesContainer.innerHTML = '';277            278            // Display recipes279            recipes.forEach(recipe => {280                const recipeCard = document.createElement('div');281                recipeCard.className = 'recipe-card bg-white rounded-xl shadow-md overflow-hidden';282                recipeCard.innerHTML = `283<img src="${recipe.image}" alt="${recipe.label}" class="w-full h-48 object-cover">284                    <div class="p-6">285                        <h3 class="text-xl font-semibold text-dark mb-2">${recipe.label}</h3>286                        <div class="flex items-center text-sm text-gray-500 mb-3">287                            <span class="flex items-center mr-4"><i data-feather="clock" class="w-4 h-4 mr-1"></i> ${Math.round(recipe.totalTime)} mins</span>288                            <span class="flex items-center"><i data-feather="activity" class="w-4 h-4 mr-1"></i> ${recipe.calories ? Math.round(recipe.calories/recipe.yield) : 'N/A'} cal/serving</span>289                        </div>290                        <div class="mb-4">291                            ${recipe.ingredientLines.slice(0, 3).map(ing => `<span class="ingredient-tag">${ing}</span>`).join('')}292                        </div>293                        <a href="${recipe.url}" class="block w-full bg-accent hover:bg-yellow-500 text-dark font-medium py-2 px-4 rounded-lg transition text-center">294                            View Recipe295                        </a>296</div>297                `;298                recipesContainer.appendChild(recipeCard);299            });300});301        recipesSection.classList.remove('hidden');302        feather.replace();303        } catch (error) {304            console.error('Error finding recipes:', error);305            recipesContainer.innerHTML = `306                <div class="text-center col-span-3 py-8">307                    <i data-feather="frown" class="w-12 h-12 text-red-500 mx-auto mb-4"></i>308                    <h3 class="text-xl font-medium text-dark mb-2">Recipe Search Failed</h3>309                    <p class="text-gray-600 mb-4">We couldn't find recipes matching your ingredients.</p>310                    <button onclick="window.location.reload()" class="bg-primary hover:bg-red-600 text-white px-6 py-2 rounded-lg flex items-center gap-2 transition mx-auto">311                        <i data-feather="refresh-cw"></i> Try Again312                    </button>313                </div>314            `;315            feather.replace();316}317    }318// Clean up camera on page exit319    window.addEventListener('beforeunload', () => {320        stopCamera();321    });322});