Page Design: 1. Page Background: High-definition farm image (featuring straw, green crops, etc.) 2. A button displaying “Upload Crop Images” in both Chinese and English is positioned at the center of the upper portion of the page. 3. In the remaining blank areas of the page, I require 18 floating circles of varying sizes. These circles will be used to insert my local images. Note that these floating circles should have some shadow effects for aesthetic purposes. When the mouse hovers over a floating circle, a box should appear displaying the corresponding pest or disease type. Functional Design: 1. A button is positioned at the center of the upper part of the page. Button function: Clicking the button opens a dialog box to select crop photos from the local computer. After confirming the selection, the photos are uploaded to our model for processing, which outputs the pest or disease type of the crops. - Initial Deployment
e94413f verified | <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Crop Disease Detection</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| body { | |
| background-image: url('https://images.unsplash.com/photo-1500382017468-9049fed747ef?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2070&q=80'); | |
| background-size: cover; | |
| background-position: center; | |
| background-attachment: fixed; | |
| min-height: 100vh; | |
| position: relative; | |
| overflow-x: hidden; | |
| } | |
| .circle { | |
| position: absolute; | |
| border-radius: 50%; | |
| background-color: rgba(255, 255, 255, 0.8); | |
| box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2); | |
| transition: all 0.3s ease; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| overflow: hidden; | |
| cursor: pointer; | |
| } | |
| .circle:hover { | |
| transform: scale(1.1); | |
| box-shadow: 0 8px 25px rgba(0, 0, 0, 0.3); | |
| } | |
| .circle img { | |
| width: 100%; | |
| height: 100%; | |
| object-fit: cover; | |
| } | |
| .tooltip { | |
| position: absolute; | |
| bottom: -40px; | |
| left: 50%; | |
| transform: translateX(-50%); | |
| background-color: rgba(0, 0, 0, 0.8); | |
| color: white; | |
| padding: 5px 10px; | |
| border-radius: 5px; | |
| font-size: 12px; | |
| white-space: nowrap; | |
| opacity: 0; | |
| transition: opacity 0.3s; | |
| pointer-events: none; | |
| } | |
| .circle:hover .tooltip { | |
| opacity: 1; | |
| } | |
| .modal { | |
| transition: opacity 0.3s ease; | |
| } | |
| .modal-overlay { | |
| background-color: rgba(0, 0, 0, 0.5); | |
| } | |
| @keyframes float { | |
| 0% { transform: translateY(0px); } | |
| 50% { transform: translateY(-10px); } | |
| 100% { transform: translateY(0px); } | |
| } | |
| .floating { | |
| animation: float 4s ease-in-out infinite; | |
| } | |
| .floating:nth-child(2n) { | |
| animation-delay: 0.5s; | |
| } | |
| .floating:nth-child(3n) { | |
| animation-delay: 1s; | |
| } | |
| </style> | |
| </head> | |
| <body class="font-sans"> | |
| <!-- Main Content --> | |
| <div class="container mx-auto px-4 py-8 relative z-10"> | |
| <!-- Upload Button --> | |
| <div class="flex justify-center mt-8 md:mt-16"> | |
| <button id="uploadBtn" class="bg-green-600 hover:bg-green-700 text-white font-bold py-4 px-8 rounded-full shadow-lg transition duration-300 transform hover:scale-105 flex items-center"> | |
| <i class="fas fa-cloud-upload-alt text-xl mr-3"></i> | |
| <span> | |
| <span class="block">Upload Crop Images</span> | |
| <span class="block text-sm font-normal">上传作物图片</span> | |
| </span> | |
| </button> | |
| </div> | |
| <!-- Hidden File Input --> | |
| <input type="file" id="fileInput" class="hidden" accept="image/*" multiple> | |
| </div> | |
| <!-- Floating Circles Container --> | |
| <div id="circlesContainer" class="absolute inset-0 overflow-hidden pointer-events-none"> | |
| <!-- Circles will be dynamically added here --> | |
| </div> | |
| <!-- Modal Dialog --> | |
| <div id="uploadModal" class="fixed inset-0 flex items-center justify-center z-50 modal opacity-0 pointer-events-none transition-opacity"> | |
| <div class="modal-overlay absolute inset-0"></div> | |
| <div class="bg-white rounded-lg shadow-xl max-w-md w-full mx-4 relative z-10 p-6"> | |
| <div class="flex justify-between items-center mb-4"> | |
| <h3 class="text-xl font-bold text-gray-800">Upload Images</h3> | |
| <button id="closeModal" class="text-gray-500 hover:text-gray-700"> | |
| <i class="fas fa-times"></i> | |
| </button> | |
| </div> | |
| <div class="mb-4"> | |
| <p class="text-gray-600">Please select crop images to analyze for pests and diseases.</p> | |
| </div> | |
| <div class="flex justify-end space-x-3"> | |
| <button id="cancelUpload" class="px-4 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50">Cancel</button> | |
| <button id="confirmUpload" class="px-4 py-2 bg-green-600 text-white rounded-md hover:bg-green-700">Upload & Analyze</button> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Processing Modal --> | |
| <div id="processingModal" class="fixed inset-0 flex items-center justify-center z-50 hidden"> | |
| <div class="modal-overlay absolute inset-0"></div> | |
| <div class="bg-white rounded-lg shadow-xl max-w-md w-full mx-4 relative z-10 p-6"> | |
| <div class="flex flex-col items-center"> | |
| <div class="animate-spin rounded-full h-12 w-12 border-t-2 border-b-2 border-green-600 mb-4"></div> | |
| <h3 class="text-xl font-bold text-gray-800 mb-2">Processing Images</h3> | |
| <p class="text-gray-600 text-center">Analyzing your crop images for pests and diseases. This may take a moment...</p> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| document.addEventListener('DOMContentLoaded', function() { | |
| // Elements | |
| const uploadBtn = document.getElementById('uploadBtn'); | |
| const fileInput = document.getElementById('fileInput'); | |
| const uploadModal = document.getElementById('uploadModal'); | |
| const closeModal = document.getElementById('closeModal'); | |
| const cancelUpload = document.getElementById('cancelUpload'); | |
| const confirmUpload = document.getElementById('confirmUpload'); | |
| const processingModal = document.getElementById('processingModal'); | |
| const circlesContainer = document.getElementById('circlesContainer'); | |
| // Pest and disease types (for tooltips) | |
| const pestTypes = [ | |
| "Aphids (蚜虫)", "Whiteflies (白粉虱)", "Spider Mites (红蜘蛛)", | |
| "Thrips (蓟马)", "Leaf Miners (潜叶蝇)", "Mealybugs (粉蚧)", | |
| "Scale Insects (介壳虫)", "Caterpillars (毛虫)", "Beetles (甲虫)", | |
| "Powdery Mildew (白粉病)", "Downy Mildew (霜霉病)", "Rust (锈病)", | |
| "Blight (枯萎病)", "Leaf Spot (叶斑病)", "Root Rot (根腐病)", | |
| "Wilt (萎蔫病)", "Mosaic Virus (花叶病毒)", "Bacterial Spot (细菌性斑点病)" | |
| ]; | |
| // Create floating circles | |
| function createCircles() { | |
| const sizes = [60, 70, 80, 90, 100]; | |
| const colors = [ | |
| 'bg-red-100', 'bg-blue-100', 'bg-green-100', 'bg-yellow-100', | |
| 'bg-purple-100', 'bg-pink-100', 'bg-indigo-100', 'bg-teal-100' | |
| ]; | |
| for (let i = 0; i < 18; i++) { | |
| const circle = document.createElement('div'); | |
| const size = sizes[Math.floor(Math.random() * sizes.length)]; | |
| const color = colors[Math.floor(Math.random() * colors.length)]; | |
| const left = Math.random() * 90; | |
| const top = Math.random() * 80 + 10; // Avoid top 10% | |
| circle.className = `circle floating ${color} pointer-events-auto`; | |
| circle.style.width = `${size}px`; | |
| circle.style.height = `${size}px`; | |
| circle.style.left = `${left}%`; | |
| circle.style.top = `${top}%`; | |
| // Add tooltip | |
| const tooltip = document.createElement('div'); | |
| tooltip.className = 'tooltip'; | |
| tooltip.textContent = pestTypes[i]; | |
| circle.appendChild(tooltip); | |
| // Add placeholder icon | |
| const icon = document.createElement('i'); | |
| const icons = [ | |
| 'fa-bug', 'fa-leaf', 'fa-spider', 'fa-bacteria', | |
| 'fa-virus', 'fa-seedling', 'fa-tree', 'fa-wheat-awn' | |
| ]; | |
| icon.className = `fas ${icons[Math.floor(Math.random() * icons.length)]} text-2xl text-gray-700`; | |
| circle.appendChild(icon); | |
| circlesContainer.appendChild(circle); | |
| // Make circles draggable | |
| makeDraggable(circle); | |
| } | |
| } | |
| // Make elements draggable | |
| function makeDraggable(element) { | |
| let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0; | |
| element.onmousedown = dragMouseDown; | |
| function dragMouseDown(e) { | |
| e = e || window.event; | |
| e.preventDefault(); | |
| // get the mouse cursor position at startup: | |
| pos3 = e.clientX; | |
| pos4 = e.clientY; | |
| document.onmouseup = closeDragElement; | |
| // call a function whenever the cursor moves: | |
| document.onmousemove = elementDrag; | |
| } | |
| function elementDrag(e) { | |
| e = e || window.event; | |
| e.preventDefault(); | |
| // calculate the new cursor position: | |
| pos1 = pos3 - e.clientX; | |
| pos2 = pos4 - e.clientY; | |
| pos3 = e.clientX; | |
| pos4 = e.clientY; | |
| // set the element's new position: | |
| element.style.top = (element.offsetTop - pos2) + "px"; | |
| element.style.left = (element.offsetLeft - pos1) + "px"; | |
| } | |
| function closeDragElement() { | |
| // stop moving when mouse button is released: | |
| document.onmouseup = null; | |
| document.onmousemove = null; | |
| } | |
| } | |
| // Show upload modal | |
| uploadBtn.addEventListener('click', () => { | |
| fileInput.click(); | |
| }); | |
| // File input change handler | |
| fileInput.addEventListener('change', () => { | |
| if (fileInput.files.length > 0) { | |
| showModal(); | |
| } | |
| }); | |
| // Show modal function | |
| function showModal() { | |
| uploadModal.classList.remove('opacity-0', 'pointer-events-none'); | |
| uploadModal.classList.add('opacity-100', 'pointer-events-auto'); | |
| } | |
| // Hide modal function | |
| function hideModal() { | |
| uploadModal.classList.remove('opacity-100', 'pointer-events-auto'); | |
| uploadModal.classList.add('opacity-0', 'pointer-events-none'); | |
| fileInput.value = ''; // Reset file input | |
| } | |
| // Close modal buttons | |
| closeModal.addEventListener('click', hideModal); | |
| cancelUpload.addEventListener('click', hideModal); | |
| // Confirm upload | |
| confirmUpload.addEventListener('click', () => { | |
| hideModal(); | |
| processingModal.classList.remove('hidden'); | |
| // Simulate processing delay | |
| setTimeout(() => { | |
| processingModal.classList.add('hidden'); | |
| // Here you would normally send the images to your model | |
| // For demo purposes, we'll just show an alert | |
| alert('Analysis complete! The results have been added to the floating circles.'); | |
| // Update some circles with example results | |
| updateCirclesWithResults(); | |
| }, 3000); | |
| }); | |
| // Function to update circles with example results | |
| function updateCirclesWithResults() { | |
| const circles = document.querySelectorAll('.circle'); | |
| const exampleImages = [ | |
| 'https://images.unsplash.com/photo-1596541223131-891a3a5754a3?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2070&q=80', | |
| 'https://images.unsplash.com/photo-1518492104633-130d0b9796a7?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2070&q=80', | |
| 'https://images.unsplash.com/photo-1586771107445-d3ca888129ce?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2070&q=80' | |
| ]; | |
| // Update first 3 circles with example images | |
| for (let i = 0; i < 3 && i < circles.length; i++) { | |
| const circle = circles[i]; | |
| // Remove icon | |
| if (circle.querySelector('i')) { | |
| circle.querySelector('i').remove(); | |
| } | |
| // Add image | |
| const img = document.createElement('img'); | |
| img.src = exampleImages[i]; | |
| img.alt = 'Detected pest or disease'; | |
| circle.appendChild(img); | |
| // Update tooltip with confidence level | |
| if (circle.querySelector('.tooltip')) { | |
| circle.querySelector('.tooltip').textContent = | |
| `${pestTypes[i]} (${Math.floor(Math.random() * 30) + 70}% confidence)`; | |
| } | |
| } | |
| } | |
| // Initialize circles | |
| createCircles(); | |
| }); | |
| </script> | |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Yango1/https-huggingface-co-spaces-yango1-crops" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |