Itsdockertest / static /index.html
Ashrafb's picture
Update static/index.html
26cc82f verified
<div class="ai-tool-container">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.13.11/katex.min.css">
<link href="https://fonts.googleapis.com/css2?family=Barlow+Condensed:wght@100&display=swap" rel="stylesheet">
<div class="container">
<h3>Image to sketch</h3>
<form id="remakeai-form">
<div class="form-group">
<label for="file" class="custom-file-upload">
<i class="fa fa-cloud-upload"></i> Upload Image
</label>
<input type="file" id="file" name="file" required>
<span id="file-name"></span>
</div>
<button type="submit" class="btn-submit">Submit</button>
</form>
<div class="result"></div>
<div class="progress-container">
<div class="progress-bar" id="progress-bar"></div>
</div>
</div>
</div>
<script>
document.addEventListener("DOMContentLoaded", function() {
const form = document.getElementById("remakeai-form");
const fileInput = document.getElementById('file');
const fileNameSpan = document.getElementById('file-name');
const progressBar = document.getElementById('progress-bar');
const progressContainer = document.querySelector('.progress-container');
const resultDiv = document.querySelector(".result");
let simulatedProgressInterval;
let simulatedProgress = 0;
fileInput.addEventListener('change', function() {
fileNameSpan.textContent = this.files[0].name;
});
form.addEventListener("submit", async function(event) {
event.preventDefault();
const file = fileInput.files[0];
const compressedFile = await compressImage(file);
const formData = new FormData();
formData.append('file', compressedFile, file.name);
// Reset and show the progress bar
progressBar.style.width = '0%';
progressContainer.style.display = 'block';
simulatedProgress = 0;
// Clear previous result
resultDiv.innerHTML = '';
const xhr = new XMLHttpRequest();
xhr.open("POST", "/upload/", true);
xhr.responseType = 'json'; // Ensure the response is treated as JSON
xhr.upload.onprogress = function(event) {
if (event.lengthComputable) {
const percentComplete = (event.loaded / event.total) * 100;
updateProgressBar(percentComplete);
}
};
xhr.onloadstart = function() {
// Start simulating progress during backend processing
simulateBackendProcessingProgress();
};
xhr.onload = function() {
clearInterval(simulatedProgressInterval); // Stop simulation
if (xhr.status === 200) {
const response = xhr.response;
if (response.error) {
resultDiv.innerHTML = `<p class="error-message">${response.error}</p>`;
} else {
const originalURL = URL.createObjectURL(file);
const sketchImageBase64 = response.sketch_image_base64;
resultDiv.innerHTML = `
<h2>Result</h2>
<div class="result-images">
<img src="${originalURL}" alt="Original Image" class="result-image">
<span class="arrow">↓</span>
<img src="${sketchImageBase64}" alt="Sketch Image" class="result-image">
</div>
`;
// Create and append the download button
const downloadButton = document.createElement('a');
downloadButton.href = sketchImageBase64;
downloadButton.download = 'result.jpg';
downloadButton.textContent = 'Download Result';
downloadButton.className = 'btn-download';
resultDiv.appendChild(downloadButton);
updateProgressBar(100);
}
} else {
resultDiv.innerHTML = `<p class="error-message">Error: ${xhr.statusText}</p>`;
updateProgressBar(0);
}
setTimeout(() => {
progressContainer.style.display = 'none';
}, 1000);
};
xhr.onerror = function() {
clearInterval(simulatedProgressInterval); // Stop simulation
resultDiv.innerHTML = `<p class="error-message">Error: Network Error</p>`;
updateProgressBar(0);
setTimeout(() => {
progressContainer.style.display = 'none';
}, 1000);
};
xhr.send(formData);
});
async function compressImage(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = function(event) {
const img = new Image();
img.src = event.target.result;
img.onload = function() {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// Calculate the new dimensions to resize the image while maintaining aspect ratio
const maxWidth = 1000;
const maxHeight = 1000;
let width = img.width;
let height = img.height;
if (width > height) {
if (width > maxWidth) {
height *= maxWidth / width;
width = maxWidth;
}
} else {
if (height > maxHeight) {
width *= maxHeight / height;
height = maxHeight;
}
}
// Set the canvas dimensions
canvas.width = width;
canvas.height = height;
// Draw the image on the canvas with the new dimensions
ctx.drawImage(img, 0, 0, width, height);
// Convert canvas content to a blob
canvas.toBlob((blob) => {
resolve(blob);
}, 'image/jpeg', 0.7); // Adjust quality as needed (0.7 is 70% quality)
}
}
// Read the file as data URL
reader.readAsDataURL(file);
});
}
function updateProgressBar(percentComplete) {
progressBar.style.width = percentComplete + '%';
updateProgressBarColor(percentComplete);
}
function updateProgressBarColor(percentComplete) {
const startColor = "#ff0000"; // Red
const endColor = "#0056b3"; // Blue
const currentColor = interpolateColor(startColor, endColor, percentComplete / 100);
progressBar.style.backgroundColor = currentColor;
}
function interpolateColor(color1, color2, factor) {
const result = color1.slice(1).match(/.{2}/g).map((hex, i) => {
return Math.round(parseInt(hex, 16) * (1 - factor) + parseInt(color2.slice(1).match(/.{2}/g)[i], 16) * factor);
});
return `#${result.map(val => val.toString(16).padStart(2, '0')).join('')}`;
}
function simulateBackendProcessingProgress() {
simulatedProgressInterval = setInterval(() => {
simulatedProgress += 1; // Increment progress by 1%
if (simulatedProgress < 90) { // Cap the simulated progress at 90%
updateProgressBar(simulatedProgress);
} else {
clearInterval(simulatedProgressInterval); // Stop simulation at 90%
}
}, 200); // Update every 200ms
}
});
</script>
<style>
.ai-tool-container body{
font-family: 'Barlow Condensed', sans-serif;
background: linear-gradient(135deg, #f5f7fa, #c3cfe2);
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
direction: ltr;
}
.ai-tool-container {
background: #fff;
border-radius: 10px;
box-shadow: 0 10px 15px rgba(0, 0, 0, 0.1);
padding: 20px;
max-width: 500px;
width: 100%;
text-align: center;
direction: ltr;
}
.ai-tool-container h3 {
font-size: 24px;
margin-bottom: 20px;
color: #333;
}
.ai-tool-container .form-group {
margin-bottom: 15px;
text-align: left;
}
.ai-tool-container
input[type="file"] {
display: none;
}
.ai-tool-container .custom-file-upload {
display: inline-block;
padding: 10px 20px;
cursor: pointer;
background-color: #007bff;
color: #fff;
border-radius: 5px;
transition: background 0.3s;
}
.ai-tool-container .custom-file-upload:hover {
background-color: #0056b3;
}
.ai-tool-container #file-name {
display: block;
margin-top: 10px;
font-size: 14px;
color: #555;
}
.ai-tool-container .radio-group {
display: flex;
justify-content: space-around;
align-items: center;
}
.ai-tool-container .btn-submit {
background: #007bff;
color: #fff;
padding: 10px 20px;
border: none;
border-radius: 5px;
cursor: pointer;
transition: background 0.3s;
}
.ai-tool-container .btn-submit:hover {
background: #0056b3;
}
.ai-tool-container .result {
margin-top: 20px;
}
.ai-tool-container .result h2 {
font-size: 20px;
color: #333;
}
.ai-tool-container .result-image {
max-width: 100%;
border-radius: 10px;
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.1);
transition: transform 0.3s;
}
.ai-tool-container .result-image:hover {
transform: scale(1.05);
}
.ai-tool-container .error-message {
color: red;
font-size: 16px;
}
.ai-tool-container .progress-container {
width: 100%;
background-color: #f3f3f3;
border-radius: 5px;
overflow: hidden;
margin-top: 20px;
display: none;
}
.ai-tool-container .progress-bar {
height: 10px;
width: 0%;
transition: width 0.4s ease, background-color 0.4s ease;
}
.ai-tool-container .result-images {
display: flex;
align-items: center;
justify-content: center;
}
.ai-tool-container .result-images {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.ai-tool-container .result-image {
max-width: 100%;
max-height: 300px;
border-radius: 10px;
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.1);
transition: transform 0.3s;
margin: 10px 0;
}
.ai-tool-container .result-image:hover {
transform: scale(1.05);
}
.ai-tool-container .arrow {
font-size: 24px;
color: #333;
margin: 10px 0;
}
.ai-tool-container .btn-download {
display: inline-block;
margin-top: 20px;
padding: 10px 20px;
background-color: #708090;
color: #fff;
border-radius: 5px;
text-decoration: none;
transition: background 0.3s;
}
.ai-tool-container .btn-download:hover {
background-color: #218838;
}
</style>
</div>