// DOM элементы
const uploadArea = document.getElementById('uploadArea');
const fileInput = document.getElementById('fileInput');
const selectFileBtn = document.getElementById('selectFileBtn');
const previewArea = document.getElementById('previewArea');
const previewImg = document.getElementById('previewImg');
const removeImageBtn = document.getElementById('removeImageBtn');
const predictBtn = document.getElementById('predictBtn');
const resultsArea = document.getElementById('resultsArea');
const loading = document.getElementById('loading');
const errorMessage = document.getElementById('errorMessage');
let currentFile = null;
// API базовый URL
const API_URL = window.location.origin + '/api/v1';
// Обработчики событий
selectFileBtn.addEventListener('click', () => fileInput.click());
removeImageBtn.addEventListener('click', clearImage);
predictBtn.addEventListener('click', predictImage);
fileInput.addEventListener('change', handleFileSelect);
// Drag & Drop
uploadArea.addEventListener('dragover', (e) => {
e.preventDefault();
uploadArea.classList.add('drag-over');
});
uploadArea.addEventListener('dragleave', () => {
uploadArea.classList.remove('drag-over');
});
uploadArea.addEventListener('drop', (e) => {
e.preventDefault();
uploadArea.classList.remove('drag-over');
const file = e.dataTransfer.files[0];
if (file && file.type.startsWith('image/')) {
handleFile(file);
} else {
showError('Пожалуйста, загрузите изображение');
}
});
uploadArea.addEventListener('click', () => fileInput.click());
function handleFileSelect(e) {
const file = e.target.files[0];
if (file) {
handleFile(file);
}
}
function handleFile(file) {
// Проверка размера (10 MB)
if (file.size > 10 * 1024 * 1024) {
showError('Файл слишком большой. Максимум 10 MB');
return;
}
currentFile = file;
// Предпросмотр
const reader = new FileReader();
reader.onload = (e) => {
previewImg.src = e.target.result;
uploadArea.style.display = 'none';
previewArea.style.display = 'block';
resultsArea.style.display = 'none';
hideError();
};
reader.readAsDataURL(file);
}
function clearImage() {
currentFile = null;
fileInput.value = '';
previewArea.style.display = 'none';
uploadArea.style.display = 'block';
resultsArea.style.display = 'none';
hideError();
}
async function predictImage() {
if (!currentFile) {
showError('Сначала выберите изображение');
return;
}
// Показываем загрузку
loading.style.display = 'block';
resultsArea.style.display = 'none';
hideError();
// Создаем FormData
const formData = new FormData();
formData.append('file', currentFile);
try {
// Отправляем запрос
const response = await fetch(`${API_URL}/predict`, {
method: 'POST',
body: formData
});
const data = await response.json();
if (!response.ok) {
throw new Error(data.error?.message || 'Ошибка при обработке');
}
// Отображаем результаты
displayResults(data.data);
} catch (error) {
console.error('Error:', error);
showError(error.message || 'Ошибка при отправке запроса');
} finally {
loading.style.display = 'none';
}
}
function displayResults(data) {
const resultClass = document.getElementById('resultClass');
const resultConfidence = document.getElementById('resultConfidence');
const probabilitiesDiv = document.getElementById('probabilities');
// Определяем эмодзи для класса
let emoji = '';
if (data.class === 'pered') emoji = '🚂 Передняя часть';
else if (data.class === 'zad') emoji = '🚂 Задняя часть';
else emoji = '⭕ Вагон не обнаружен';
// Отображаем основной результат
resultClass.innerHTML = `${emoji}
${data.class_name}`;
resultConfidence.innerHTML = `Уверенность: ${(data.confidence * 100).toFixed(1)}%`;
// Отображаем все вероятности
probabilitiesDiv.innerHTML = '