Spaces:
Runtime error
Runtime error
| document.addEventListener("DOMContentLoaded", () => { | |
| let lastUploadedImage = null; | |
| const dropzone = document.getElementById("dropzone"); | |
| const featureSelect = document.getElementById("feature-select"); | |
| const thinkingText = document.getElementById("thinking-text"); | |
| function handleImageUpload(file) { | |
| const predictedImagesContainer = document.getElementById("predicted-images"); | |
| predictedImagesContainer.innerHTML = ""; | |
| const predictionContainer = document.getElementById("prediction-container"); | |
| const imageElement = document.createElement("img"); | |
| imageElement.src = "static/loading.gif"; | |
| imageElement.style.height = "100px"; | |
| imageElement.style.width = "100px"; | |
| imageElement.style.margin = 'auto'; | |
| predictionContainer.appendChild(imageElement); | |
| const selectedFeature = featureSelect.value; | |
| const formData = new FormData(); | |
| thinkingText.innerText = ""; | |
| formData.append("uploaded-image", file); | |
| formData.append("feature", selectedFeature); | |
| lastUploadedImage = file; | |
| fetch("/guess", { | |
| method: "POST", | |
| body: formData, | |
| }) | |
| .then((response) => response.json()) | |
| .then((data) => { | |
| console.log(data); | |
| displayResults(data); | |
| }) | |
| .catch((error) => { | |
| console.error("Error uploading image:", error); | |
| }); | |
| const reader = new FileReader(); | |
| reader.onloadend = () => { | |
| const uploadedImage = new Image(); | |
| uploadedImage.src = reader.result; | |
| uploadedImage.classList.add("uploaded-image"); | |
| uploadedImage.onload = async () => { | |
| const imageWidth = uploadedImage.width; | |
| const imageHeight = uploadedImage.height; | |
| const imageSize = 300; | |
| // Create a canvas to draw cropped image | |
| const canvas = document.createElement("canvas"); | |
| const ctx = canvas.getContext("2d"); | |
| canvas.width = imageSize; | |
| canvas.height = imageSize; | |
| let sourceX, sourceY, sourceWidth, sourceHeight; | |
| if (imageWidth > imageHeight) { | |
| // Image is wider than it is tall | |
| sourceHeight = imageHeight; | |
| sourceWidth = imageHeight; | |
| sourceX = (imageWidth - sourceWidth) / 2; | |
| sourceY = 0; | |
| } else { | |
| // Image is taller than it is wide or square | |
| sourceWidth = imageWidth; | |
| sourceHeight = imageWidth; | |
| sourceY = (imageHeight - sourceHeight) / 2; | |
| sourceX = 0; | |
| } | |
| ctx.drawImage(uploadedImage, sourceX, sourceY, sourceWidth, sourceHeight, 0, 0, imageSize, imageSize); | |
| const croppedImage = new Image(); | |
| croppedImage.src = canvas.toDataURL(); | |
| croppedImage.classList.add("uploaded-image"); | |
| dropzone.innerHTML = ""; | |
| dropzone.appendChild(croppedImage); | |
| }; | |
| }; | |
| if (file) { | |
| reader.readAsDataURL(file); | |
| } | |
| } | |
| dropzone.addEventListener("click", () => { | |
| const fileInput = document.createElement("input"); | |
| fileInput.type = "file"; | |
| fileInput.accept = "image/*"; | |
| fileInput.onchange = (e) => { | |
| const file = e.target.files[0]; | |
| handleImageUpload(file); | |
| }; | |
| fileInput.click(); | |
| }); | |
| dropzone.addEventListener("dragover", (e) => { | |
| e.preventDefault(); | |
| dropzone.classList.add("highlight"); | |
| }); | |
| dropzone.addEventListener("dragleave", () => { | |
| dropzone.classList.remove("highlight"); | |
| }); | |
| dropzone.addEventListener("drop", (e) => { | |
| e.preventDefault(); | |
| dropzone.classList.remove("highlight"); | |
| const file = e.dataTransfer.files[0]; | |
| handleImageUpload(file); | |
| }); | |
| featureSelect.addEventListener("change", () => { | |
| if (lastUploadedImage) { | |
| handleImageUpload(lastUploadedImage); | |
| } | |
| }); | |
| function displayResults(data) { | |
| thinkingText.innerText = ""; | |
| const predictionContainer = document.getElementById("prediction-container"); | |
| const loadingImage = predictionContainer.querySelector('img[src="static/loading.gif"]'); | |
| if (loadingImage) { | |
| predictionContainer.removeChild(loadingImage); | |
| } | |
| const predictedImagesContainer = document.getElementById("predicted-images"); | |
| predictedImagesContainer.innerHTML = ""; // Clear previous images | |
| for (let i = 0; i < data.images.length; i++) { | |
| const imageUrl = data.images[i]; | |
| const predictionUrl = data.predictions[i]; | |
| const name = data.names[i]; | |
| const species = data.species[i]; | |
| // Create a container div for each image and its anchor | |
| const imageContainer = document.createElement("div"); | |
| // Create the anchor element | |
| const anchorElement = document.createElement("a"); | |
| anchorElement.href = predictionUrl; | |
| anchorElement.target = "_blank"; // Open the link in a new tab | |
| // Create the caption element | |
| const captionElement = document.createElement("div"); | |
| captionElement.classList.add("image-caption"); | |
| captionElement.textContent = name; // Use the name from the 'names' list as the caption text | |
| // Create the caption element | |
| const speciesElement = document.createElement("div"); | |
| speciesElement.classList.add("image-species"); | |
| speciesElement.textContent = species; // Use the name from the 'names' list as the caption text | |
| // Create the image element | |
| const imageElement = document.createElement("img"); | |
| // Add cache-busting parameter to the image URL | |
| const cacheBustUrl = imageUrl + `?cache=${Date.now()}`; | |
| // Set the lazy loading attribute | |
| imageElement.loading = "lazy"; | |
| // Set the data-src attribute with the cache-busted URL | |
| imageElement.src = cacheBustUrl; | |
| const tooltip = document.createElement("div"); | |
| tooltip.classList.add("image-tooltip"); | |
| tooltip.textContent = species; // Use the name from the 'names' list as the tooltip text | |
| // Append the image to the anchor and the anchor to the container | |
| anchorElement.appendChild(imageElement); | |
| anchorElement.appendChild(captionElement); | |
| imageContainer.appendChild(tooltip); | |
| imageContainer.appendChild(anchorElement); | |
| captionElement.style.opacity = "0"; | |
| captionElement.style.opacity = "1"; | |
| // Append the container to the predictedImagesContainer | |
| predictedImagesContainer.appendChild(imageContainer); | |
| // Add the tooltip element to the document body | |
| document.body.appendChild(tooltip); | |
| // Add event listeners to handle tooltip visibility | |
| imageContainer.addEventListener("mouseover", () => { | |
| tooltip.style.opacity = "1"; | |
| }); | |
| imageContainer.addEventListener("mouseout", () => { | |
| tooltip.style.opacity = "0"; | |
| }); | |
| // Position the tooltip dynamically based on cursor movement | |
| imageContainer.addEventListener("mousemove", (event) => { | |
| tooltip.style.left = event.pageX + "px"; | |
| tooltip.style.top = event.pageY + "px"; | |
| }); | |
| } | |
| } | |
| }); | |