Wiuhh's picture
Create static/js/app.js
ff177ec verified
class SketchConverter {
constructor() {
this.initializeElements();
this.attachEventListeners();
this.currentFile = null;
this.currentSketchUrl = null;
}
initializeElements() {
this.uploadArea = document.getElementById('upload-area');
this.processingArea = document.getElementById('processing-area');
this.resultArea = document.getElementById('result-area');
this.settingsArea = document.getElementById('settings-area');
this.fileInput = document.getElementById('file-input');
this.browseBtn = document.getElementById('browse-btn');
this.originalImage = document.getElementById('original-image');
this.sketchImage = document.getElementById('sketch-image');
this.downloadBtn = document.getElementById('download-btn');
this.newUploadBtn = document.getElementById('new-upload-btn');
this.blurSelect = document.getElementById('blur-select');
this.enhanceCheck = document.getElementById('enhance-check');
}
attachEventListeners() {
// File input and browse button
this.browseBtn.addEventListener('click', () => this.fileInput.click());
this.fileInput.addEventListener('change', (e) => this.handleFileSelect(e.target.files[0]));
// Drag and drop
this.uploadArea.addEventListener('dragover', (e) => this.handleDragOver(e));
this.uploadArea.addEventListener('dragleave', (e) => this.handleDragLeave(e));
this.uploadArea.addEventListener('drop', (e) => this.handleDrop(e));
// Result actions
this.downloadBtn.addEventListener('click', () => this.downloadSketch());
this.newUploadBtn.addEventListener('click', () => this.resetInterface());
// Settings
this.blurSelect.addEventListener('change', () => this.processCurrentFile());
this.enhanceCheck.addEventListener('change', () => this.processCurrentFile());
}
handleDragOver(e) {
e.preventDefault();
e.stopPropagation();
this.uploadArea.classList.add('border-primary');
}
handleDragLeave(e) {
e.preventDefault();
e.stopPropagation();
this.uploadArea.classList.remove('border-primary');
}
handleDrop(e) {
e.preventDefault();
e.stopPropagation();
this.uploadArea.classList.remove('border-primary');
const files = e.dataTransfer.files;
if (files.length > 0) {
this.handleFileSelect(files[0]);
}
}
handleFileSelect(file) {
if (!file) return;
// Validate file type
if (!file.type.startsWith('image/')) {
this.showError('Please select a valid image file (JPG, PNG, etc.)');
return;
}
// Validate file size (max 10MB)
if (file.size > 10 * 1024 * 1024) {
this.showError('File size must be less than 10MB');
return;
}
this.currentFile = file;
this.showOriginalImage(file);
this.processCurrentFile();
}
showOriginalImage(file) {
const reader = new FileReader();
reader.onload = (e) => {
this.originalImage.src = e.target.result;
};
reader.readAsDataURL(file);
}
async processCurrentFile() {
if (!this.currentFile) return;
this.showProcessing();
const formData = new FormData();
formData.append('image', this.currentFile);
formData.append('blur', this.blurSelect.value);
formData.append('enhance', this.enhanceCheck.checked);
try {
const response = await fetch('/convert', {
method: 'POST',
body: formData
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(errorData.error || 'Failed to process image');
}
const result = await response.json();
this.showResult(result.sketch_url);
} catch (error) {
console.error('Error processing image:', error);
this.showError(error.message || 'Failed to process image. Please try again.');
}
}
showProcessing() {
this.hideAllAreas();
this.processingArea.classList.remove('hidden');
this.settingsArea.classList.remove('hidden');
}
showResult(sketchUrl) {
this.currentSketchUrl = sketchUrl;
this.sketchImage.src = sketchUrl;
this.hideAllAreas();
this.resultArea.classList.remove('hidden');
this.settingsArea.classList.remove('hidden');
}
hideAllAreas() {
this.uploadArea.classList.add('hidden');
this.processingArea.classList.add('hidden');
this.resultArea.classList.add('hidden');
this.settingsArea.classList.add('hidden');
}
resetInterface() {
this.currentFile = null;
this.currentSketchUrl = null;
this.fileInput.value = '';
this.hideAllAreas();
this.uploadArea.classList.remove('hidden');
// Reset settings to defaults
this.blurSelect.value = '21';
this.enhanceCheck.checked = false;
}
downloadSketch() {
if (!this.currentSketchUrl) return;
const link = document.createElement('a');
link.href = this.currentSketchUrl;
link.download = 'sketch.jpg';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
showError(message) {
// Create a simple toast notification
const toast = document.createElement('div');
toast.className = 'fixed top-4 right-4 bg-red-500 text-white px-6 py-3 rounded-lg z-50';
toast.textContent = message;
document.body.appendChild(toast);
setTimeout(() => {
document.body.removeChild(toast);
}, 5000);
this.resetInterface();
}
}
// Initialize the application when DOM is loaded
document.addEventListener('DOMContentLoaded', () => {
new SketchConverter();
});