dfernandezl12 commited on
Commit
4f4f566
·
verified ·
1 Parent(s): c7b6d29

Upload app.js

Browse files
Files changed (1) hide show
  1. app.js +167 -0
app.js ADDED
@@ -0,0 +1,167 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const API_URL = window.location.origin + '/predict'; // Ajusta si es necesario
2
+
3
+ const uploadArea = document.getElementById('uploadArea');
4
+ const fileInput = document.getElementById('fileInput');
5
+ const previewSection = document.getElementById('previewSection');
6
+ const previewImage = document.getElementById('previewImage');
7
+ const predictBtn = document.getElementById('predictBtn');
8
+ const spinner = document.getElementById('spinner');
9
+ const btnText = document.getElementById('btnText');
10
+ const resultSection = document.getElementById('resultSection');
11
+ const resultIcon = document.getElementById('resultIcon');
12
+ const resultPrediction = document.getElementById('resultPrediction');
13
+ const confidenceBar = document.getElementById('confidenceBar');
14
+ const confidenceValue = document.getElementById('confidenceValue');
15
+ const probabilitiesList = document.getElementById('probabilitiesList');
16
+ const uploadAnotherBtn = document.getElementById('uploadAnotherBtn');
17
+
18
+ let selectedFile = null;
19
+
20
+ // Prevenir comportamientos por defecto para drag and drop
21
+ ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
22
+ uploadArea.addEventListener(eventName, preventDefaults, false);
23
+ });
24
+
25
+ function preventDefaults(e) {
26
+ e.preventDefault();
27
+ e.stopPropagation();
28
+ }
29
+
30
+ ['dragenter', 'dragover'].forEach(eventName => {
31
+ uploadArea.addEventListener(eventName, () => uploadArea.classList.add('dragover'));
32
+ });
33
+
34
+ ['dragleave', 'drop'].forEach(eventName => {
35
+ uploadArea.addEventListener(eventName, () => uploadArea.classList.remove('dragover'));
36
+ });
37
+
38
+ uploadArea.addEventListener('drop', handleDrop);
39
+ uploadArea.addEventListener('click', () => fileInput.click());
40
+ fileInput.addEventListener('change', handleFileSelect);
41
+
42
+ function handleDrop(e) {
43
+ const dt = e.dataTransfer;
44
+ const files = dt.files;
45
+ if (files.length) {
46
+ handleFiles(files);
47
+ }
48
+ }
49
+
50
+ function handleFileSelect(e) {
51
+ handleFiles(e.target.files);
52
+ }
53
+
54
+ function handleFiles(files) {
55
+ if (!files || files.length === 0) return;
56
+ const file = files[0];
57
+ if (!file.type.startsWith('image/')) {
58
+ alert('Por favor selecciona una imagen válida (JPG, PNG, etc.)');
59
+ return;
60
+ }
61
+ selectedFile = file;
62
+
63
+ // Mostrar vista previa
64
+ const reader = new FileReader();
65
+ reader.onload = (e) => {
66
+ previewImage.src = e.target.result;
67
+ previewSection.classList.add('active');
68
+ predictBtn.disabled = false;
69
+ // Ocultar resultado anterior
70
+ resultSection.classList.remove('active');
71
+ uploadAnotherBtn.style.display = 'none';
72
+ };
73
+ reader.readAsDataURL(file);
74
+ }
75
+
76
+ predictBtn.addEventListener('click', classifyImage);
77
+
78
+ async function classifyImage() {
79
+ if (!selectedFile) return;
80
+
81
+ // Estado de carga
82
+ predictBtn.disabled = true;
83
+ spinner.style.display = 'inline-block';
84
+ btnText.textContent = 'Analizando...';
85
+ resultSection.classList.remove('active');
86
+
87
+ const formData = new FormData();
88
+ formData.append('file', selectedFile);
89
+
90
+ try {
91
+ const response = await fetch(API_URL, {
92
+ method: 'POST',
93
+ body: formData
94
+ });
95
+
96
+ if (!response.ok) {
97
+ const errorData = await response.json();
98
+ throw new Error(errorData.error || 'Error en la API');
99
+ }
100
+
101
+ const data = await response.json();
102
+ displayResult(data);
103
+ } catch (error) {
104
+ alert('Error: ' + error.message);
105
+ } finally {
106
+ spinner.style.display = 'none';
107
+ btnText.textContent = '🔍 Analizar imagen';
108
+ predictBtn.disabled = false;
109
+ }
110
+ }
111
+
112
+ function displayResult(data) {
113
+ const classMapping = {
114
+ airplane: { icon: '✈️', label: 'Aéreo', color: 'linear-gradient(90deg, #4299e1, #3182ce)' },
115
+ car: { icon: '🚗', label: 'Terrestre', color: 'linear-gradient(90deg, #48bb78, #38a169)' },
116
+ ship: { icon: '🚢', label: 'Marítimo', color: 'linear-gradient(90deg, #ed8936, #dd6b20)' }
117
+ };
118
+
119
+ // Clase con mayor probabilidad
120
+ const predictedClass = Object.keys(data.probabilidades).reduce((a, b) =>
121
+ data.probabilidades[a] > data.probabilidades[b] ? a : b
122
+ );
123
+
124
+ const confianza = data.probabilidades[predictedClass];
125
+ const classInfo = classMapping[predictedClass];
126
+
127
+ resultIcon.textContent = classInfo.icon;
128
+ resultPrediction.textContent = classInfo.label;
129
+ confidenceBar.style.background = classInfo.color;
130
+
131
+ const percent = Math.round(confianza * 100);
132
+ confidenceBar.style.width = percent + '%';
133
+ confidenceValue.textContent = percent + '%';
134
+
135
+ // Construir lista de probabilidades
136
+ probabilitiesList.innerHTML = '';
137
+ const labels = {
138
+ airplane: '✈️ Aéreo',
139
+ car: '🚗 Terrestre',
140
+ ship: '🚢 Marítimo'
141
+ };
142
+
143
+ for (const [key, prob] of Object.entries(data.probabilidades)) {
144
+ const probPercent = Math.round(prob * 100);
145
+ const item = document.createElement('div');
146
+ item.className = 'prob-item';
147
+ item.innerHTML = `
148
+ <div class="prob-label">
149
+ <span>${labels[key]}</span>
150
+ </div>
151
+ <span class="prob-value">${probPercent}%</span>
152
+ `;
153
+ probabilitiesList.appendChild(item);
154
+ }
155
+
156
+ resultSection.classList.add('active');
157
+ uploadAnotherBtn.style.display = 'inline-block';
158
+ }
159
+
160
+ uploadAnotherBtn.addEventListener('click', () => {
161
+ fileInput.value = '';
162
+ selectedFile = null;
163
+ previewSection.classList.remove('active');
164
+ resultSection.classList.remove('active');
165
+ predictBtn.disabled = true;
166
+ uploadAnotherBtn.style.display = 'none';
167
+ });