Spaces:
Sleeping
Sleeping
| document.addEventListener('DOMContentLoaded', function() { | |
| // Initialize AOS Animation Library | |
| AOS.init({ | |
| duration: 800, | |
| easing: 'ease', | |
| once: true, | |
| }); | |
| // Initialize Particles.js for background animation | |
| particlesJS('particles-js', { | |
| "particles": { | |
| "number": { | |
| "value": 80, | |
| "density": { | |
| "enable": true, | |
| "value_area": 800 | |
| } | |
| }, | |
| "color": { | |
| "value": "#ffffff" | |
| }, | |
| "shape": { | |
| "type": "circle", | |
| "stroke": { | |
| "width": 0, | |
| "color": "#000000" | |
| }, | |
| "polygon": { | |
| "nb_sides": 5 | |
| } | |
| }, | |
| "opacity": { | |
| "value": 0.5, | |
| "random": false, | |
| "anim": { | |
| "enable": false, | |
| "speed": 1, | |
| "opacity_min": 0.1, | |
| "sync": false | |
| } | |
| }, | |
| "size": { | |
| "value": 3, | |
| "random": true, | |
| "anim": { | |
| "enable": false, | |
| "speed": 40, | |
| "size_min": 0.1, | |
| "sync": false | |
| } | |
| }, | |
| "line_linked": { | |
| "enable": true, | |
| "distance": 150, | |
| "color": "#ffffff", | |
| "opacity": 0.4, | |
| "width": 1 | |
| }, | |
| "move": { | |
| "enable": true, | |
| "speed": 2, | |
| "direction": "none", | |
| "random": false, | |
| "straight": false, | |
| "out_mode": "out", | |
| "bounce": false, | |
| "attract": { | |
| "enable": false, | |
| "rotateX": 600, | |
| "rotateY": 1200 | |
| } | |
| } | |
| }, | |
| "interactivity": { | |
| "detect_on": "canvas", | |
| "events": { | |
| "onhover": { | |
| "enable": true, | |
| "mode": "grab" | |
| }, | |
| "onclick": { | |
| "enable": true, | |
| "mode": "push" | |
| }, | |
| "resize": true | |
| }, | |
| "modes": { | |
| "grab": { | |
| "distance": 140, | |
| "line_linked": { | |
| "opacity": 1 | |
| } | |
| }, | |
| "bubble": { | |
| "distance": 400, | |
| "size": 40, | |
| "duration": 2, | |
| "opacity": 8, | |
| "speed": 3 | |
| }, | |
| "repulse": { | |
| "distance": 200, | |
| "duration": 0.4 | |
| }, | |
| "push": { | |
| "particles_nb": 4 | |
| }, | |
| "remove": { | |
| "particles_nb": 2 | |
| } | |
| } | |
| }, | |
| "retina_detect": true | |
| }); | |
| // Navbar scroll effect | |
| window.addEventListener('scroll', function() { | |
| const navbar = document.querySelector('.navbar'); | |
| if (window.scrollY > 100) { | |
| navbar.classList.add('scrolled'); | |
| } else { | |
| navbar.classList.remove('scrolled'); | |
| } | |
| }); | |
| // Active menu item highlighting | |
| const sections = document.querySelectorAll('section'); | |
| const navLinks = document.querySelectorAll('.navbar-nav .nav-link'); | |
| window.addEventListener('scroll', () => { | |
| let current = ''; | |
| sections.forEach(section => { | |
| const sectionTop = section.offsetTop; | |
| const sectionHeight = section.clientHeight; | |
| if (pageYOffset >= (sectionTop - 150)) { | |
| current = section.getAttribute('id'); | |
| } | |
| }); | |
| navLinks.forEach(link => { | |
| link.classList.remove('active'); | |
| if (link.getAttribute('href').substring(1) === current) { | |
| link.classList.add('active'); | |
| } | |
| }); | |
| }); | |
| // Smooth scrolling for anchor links | |
| document.querySelectorAll('a[href^="#"]').forEach(anchor => { | |
| anchor.addEventListener('click', function(e) { | |
| e.preventDefault(); | |
| const target = document.querySelector(this.getAttribute('href')); | |
| if (target) { | |
| window.scrollTo({ | |
| top: target.offsetTop - 80, | |
| behavior: 'smooth' | |
| }); | |
| } | |
| }); | |
| }); | |
| // ========================================================== | |
| // === UPDATED WATER QUALITY PREDICTION FORM SUBMISSION === | |
| // ========================================================== | |
| const waterForm = document.getElementById('water-form'); | |
| const resultContainer = document.getElementById('result-container'); | |
| // All the result elements | |
| const resultStatus = document.getElementById('result-status'); | |
| const resultMessage = document.getElementById('result-message'); | |
| const resultProbability = document.getElementById('result-probability'); | |
| const gaugeFill = document.getElementById('gauge-fill'); | |
| const recommendationsList = document.getElementById('recommendations-list'); | |
| if (waterForm) { | |
| waterForm.addEventListener('submit', function(e) { | |
| e.preventDefault(); // Stop the form from reloading | |
| // Show loading state (using your existing IDs) | |
| resultContainer.style.display = 'block'; | |
| resultStatus.textContent = 'Analyzing water parameters...'; | |
| resultStatus.className = ''; // Reset color | |
| resultMessage.textContent = 'Please wait while we process your results.'; | |
| recommendationsList.innerHTML = ''; | |
| gaugeFill.style.height = '0%'; | |
| gaugeFill.style.background = '#e0e0e0'; // Reset gauge color | |
| resultProbability.textContent = '...'; | |
| // 1. Collect form data into a JavaScript object | |
| const formData = new FormData(waterForm); | |
| const data = {}; | |
| formData.forEach((value, key) => { | |
| data[key] = value; | |
| }); | |
| // 2. Send data as JSON using jQuery.ajax (as in your original file) | |
| $.ajax({ | |
| type: 'POST', | |
| url: '/predict', // The endpoint in our Flask app | |
| data: JSON.stringify(data), // Send as a JSON string | |
| contentType: 'application/json', // Tell the server we are sending JSON | |
| success: function(response) { | |
| // Simulate processing delay for better UX | |
| setTimeout(() => { | |
| displayResults(response); | |
| }, 1000); // 1-second delay | |
| }, | |
| error: function(error) { | |
| console.log(error); | |
| resultContainer.style.display = 'block'; | |
| resultStatus.textContent = 'Prediction Error'; | |
| resultStatus.className = 'unsafe'; // Use 'unsafe' style for errors | |
| resultMessage.textContent = 'An error occurred. Please check your input values and try again.'; | |
| } | |
| }); | |
| }); | |
| } | |
| /** | |
| * This function takes the JSON response from Flask and updates the HTML. | |
| */ | |
| function displayResults(response) { | |
| if (response.error) { | |
| resultStatus.textContent = 'Error'; | |
| resultStatus.className = 'unsafe'; | |
| resultMessage.textContent = response.error; | |
| return; | |
| } | |
| const probability = response.probability; | |
| const potability = response.potability; | |
| let confidence = 0; | |
| let recommendationsHTML = ''; | |
| if (potability === 1) { | |
| // --- SAFE (POTABLE) --- | |
| confidence = probability * 100; | |
| resultStatus.textContent = 'Result: Potable (Safe)'; | |
| resultStatus.className = 'safe'; // Uses your --success color | |
| resultMessage.textContent = 'The model predicts this water is safe for consumption.'; | |
| gaugeFill.style.background = 'var(--success)'; | |
| recommendationsHTML = ` | |
| <li>Confidence in this result is high.</li> | |
| <li>Maintain regular filtering and testing schedules.</li> | |
| <li><strong>Disclaimer:</strong> This is an AI prediction and not a substitute for a professional lab test.</li> | |
| `; | |
| } else { | |
| // --- UNSAFE (NOT POTABLE) --- | |
| confidence = (1 - probability) * 100; // Confidence in the "unsafe" prediction | |
| resultStatus.textContent = 'Result: Not Potable (Unsafe)'; | |
| resultStatus.className = 'unsafe'; // Uses your --danger color | |
| resultMessage.textContent = 'The model predicts this water is unsafe for consumption.'; | |
| gaugeFill.style.background = 'var(--danger)'; | |
| recommendationsHTML = ` | |
| <li>It is strongly advised **not** to drink this water.</li> | |
| <li>Boil water before use or use a certified water filter.</li> | |
| <li>Consult a local health authority for professional testing.</li> | |
| <li><strong>Disclaimer:</strong> This is an AI prediction. Prioritize safety.</li> | |
| `; | |
| } | |
| // Update gauge | |
| resultProbability.textContent = `${confidence.toFixed(0)}%`; | |
| gaugeFill.style.height = `${confidence.toFixed(0)}%`; | |
| // Update recommendations | |
| recommendationsList.innerHTML = recommendationsHTML; | |
| // Scroll to the result | |
| resultContainer.scrollIntoView({ behavior: 'smooth', block: 'center' }); | |
| } | |
| }); |