Athspi commited on
Commit
452d71e
·
verified ·
1 Parent(s): c475c92

Update templates/index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +430 -429
templates/index.html CHANGED
@@ -1,439 +1,440 @@
1
  <!DOCTYPE html>
2
  <html lang="en">
3
  <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>AI Object Remover</title>
7
- <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap" rel="stylesheet">
8
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
- <style>
10
- :root {
11
- --primary-color: #6366f1;
12
- --secondary-color: #4f46e5;
13
- --accent-color: #8b5cf6;
14
- --background: #f8fafc;
15
- --card-bg: #ffffff;
16
- --text-primary: #1e293b;
17
- --text-secondary: #64748b;
18
- --success: #10b981;
19
- --error: #ef4444;
20
- }
21
-
22
- body {
23
- font-family: 'Poppins', sans-serif;
24
- background-color: var(--background);
25
- color: var(--text-primary);
26
- margin: 0;
27
- padding: 0;
28
- min-height: 100vh;
29
- }
30
-
31
- .container {
32
- max-width: 1200px;
33
- margin: 0 auto;
34
- padding: 2rem;
35
- }
36
-
37
- header {
38
- text-align: center;
39
- margin-bottom: 2rem;
40
- }
41
-
42
- .logo {
43
- display: flex;
44
- align-items: center;
45
- justify-content: center;
46
- gap: 1rem;
47
- margin-bottom: 1rem;
48
- }
49
-
50
- .logo i {
51
- font-size: 2.5rem;
52
- color: var(--primary-color);
53
- }
54
-
55
- h1 {
56
- font-size: 2.5rem;
57
- margin: 0;
58
- background: linear-gradient(to right, var(--primary-color), var(--accent-color));
59
- -webkit-background-clip: text;
60
- background-clip: text;
61
- color: transparent;
62
- }
63
-
64
- .subtitle {
65
- color: var(--text-secondary);
66
- margin-top: 0.5rem;
67
- font-weight: 400;
68
- }
69
-
70
- .app-container {
71
- display: grid;
72
- grid-template-columns: 1fr 1fr;
73
- gap: 2rem;
74
- }
75
-
76
- @media (max-width: 768px) {
77
- .app-container {
78
- grid-template-columns: 1fr;
79
- }
80
- }
81
-
82
- .card {
83
- background-color: var(--card-bg);
84
- border-radius: 1rem;
85
- box-shadow: 0 10px 25px rgba(0, 0, 0, 0.05);
86
- padding: 1.5rem;
87
- transition: transform 0.3s ease, box-shadow 0.3s ease;
88
- }
89
-
90
- .card:hover {
91
- transform: translateY(-5px);
92
- box-shadow: 0 15px 35px rgba(0, 0, 0, 0.1);
93
- }
94
-
95
- .upload-area {
96
- border: 2px dashed #d1d5db;
97
- border-radius: 0.75rem;
98
- padding: 2rem;
99
- text-align: center;
100
- cursor: pointer;
101
- transition: all 0.3s ease;
102
- margin-bottom: 1rem;
103
- position: relative;
104
- min-height: 200px;
105
- display: flex;
106
- align-items: center;
107
- justify-content: center;
108
- overflow: hidden;
109
- }
110
-
111
- .upload-area:hover {
112
- border-color: var(--primary-color);
113
- background-color: rgba(99, 102, 241, 0.05);
114
- }
115
-
116
- .upload-placeholder {
117
- display: flex;
118
- flex-direction: column;
119
- align-items: center;
120
- }
121
-
122
- .preview-container {
123
- position: absolute;
124
- top: 0;
125
- left: 0;
126
- width: 100%;
127
- height: 100%;
128
- display: none;
129
- align-items: center;
130
- justify-content: center;
131
- background-color: var(--card-bg);
132
- }
133
-
134
- .preview-container img {
135
- max-width: 100%;
136
- max-height: 100%;
137
- object-fit: contain;
138
- }
139
-
140
- .form-group {
141
- margin-bottom: 1.5rem;
142
- }
143
-
144
- label {
145
- display: block;
146
- margin-bottom: 0.5rem;
147
- font-weight: 500;
148
- }
149
-
150
- input[type="text"] {
151
- width: 100%;
152
- padding: 0.75rem 1rem;
153
- border-radius: 0.5rem;
154
- border: 1px solid #d1d5db;
155
- font-family: inherit;
156
- font-size: 1rem;
157
- transition: border-color 0.3s ease, box-shadow 0.3s ease;
158
- }
159
-
160
- input[type="text"]:focus {
161
- outline: none;
162
- border-color: var(--primary-color);
163
- box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.2);
164
- }
165
-
166
- .button {
167
- background-color: var(--primary-color);
168
- color: white;
169
- border: none;
170
- border-radius: 0.5rem;
171
- padding: 0.75rem 1.5rem;
172
- font-family: inherit;
173
- font-size: 1rem;
174
- font-weight: 500;
175
- cursor: pointer;
176
- transition: background-color 0.3s ease, transform 0.2s ease;
177
- display: flex;
178
- align-items: center;
179
- justify-content: center;
180
- gap: 0.5rem;
181
- width: 100%;
182
- }
183
-
184
- .button:hover {
185
- background-color: var(--secondary-color);
186
- transform: translateY(-2px);
187
- }
188
-
189
- .button:disabled {
190
- background-color: #d1d5db;
191
- cursor: not-allowed;
192
- }
193
-
194
- .result-area {
195
- display: flex;
196
- flex-direction: column;
197
- align-items: center;
198
- justify-content: center;
199
- text-align: center;
200
- min-height: 200px;
201
- position: relative;
202
- }
203
-
204
- .result-image {
205
- max-width: 100%;
206
- max-height: 300px;
207
- border-radius: 0.5rem;
208
- box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
209
- display: none;
210
- }
211
-
212
- .spinner {
213
- display: none;
214
- width: 40px;
215
- height: 40px;
216
- border: 4px solid rgba(99, 102, 241, 0.1);
217
- border-left-color: var(--primary-color);
218
- border-radius: 50%;
219
- animation: spin 1s linear infinite;
220
- }
221
-
222
- .download-btn {
223
- margin-top: 1rem;
224
- background-color: var(--success);
225
- display: none;
226
- }
227
-
228
- .error-message {
229
- color: var(--error);
230
- margin-top: 1rem;
231
- display: none;
232
- text-align: center;
233
- }
234
-
235
- @keyframes spin {
236
- to {
237
- transform: rotate(360deg);
238
- }
239
- }
240
- </style>
 
 
 
 
 
 
241
  </head>
242
  <body>
243
- <div class="container">
244
- <header>
245
- <div class="logo">
246
- <i class="fas fa-magic"></i>
247
- <h1>AI Object Remover</h1>
248
- </div>
249
- <p class="subtitle">Remove unwanted objects from your images with AI</p>
250
- </header>
251
-
252
- <div class="app-container">
253
- <div class="card">
254
- <div class="upload-area" id="uploadArea">
255
- <div class="upload-placeholder">
256
- <i class="fas fa-cloud-upload-alt"></i>
257
- <p>Click or drag & drop your image here</p>
258
- <span style="font-size: 0.85rem; color: var(--text-secondary);">Supported formats: JPG, PNG</span>
259
- </div>
260
- <div class="preview-container" id="previewContainer">
261
- <img id="imagePreview" src="#" alt="Preview">
262
- </div>
263
- </div>
264
-
265
- <div class="form-group">
266
- <label for="objectType">What do you want to remove?</label>
267
- <input type="text" id="objectType" placeholder="e.g., person, text, car..." value="text">
268
- </div>
269
-
270
- <button id="processBtn" class="button" disabled>
271
- <i class="fas fa-wand-magic-sparkles"></i>
272
- <span>Remove Object</span>
273
- </button>
274
- <p class="error-message" id="errorMessage"></p>
275
- </div>
276
-
277
- <div class="card">
278
- <div class="result-area">
279
- <div id="resultPlaceholder">
280
- <i class="fas fa-image"></i>
281
- <p>Your edited image will appear here</p>
282
- </div>
283
- <div class="spinner" id="spinner"></div>
284
- <img id="resultImage" class="result-image" src="#" alt="Result">
285
- </div>
286
- <a id="downloadBtn" class="button download-btn" download="edited-image.png">
287
- <i class="fas fa-download"></i>
288
- <span>Download Image</span>
289
- </a>
290
- </div>
291
  </div>
292
- </div>
293
-
294
- <script>
295
- const uploadArea = document.getElementById('uploadArea');
296
- const previewContainer = document.getElementById('previewContainer');
297
- const imagePreview = document.getElementById('imagePreview');
298
- const objectTypeInput = document.getElementById('objectType');
299
- const processBtn = document.getElementById('processBtn');
300
- const resultPlaceholder = document.getElementById('resultPlaceholder');
301
- const resultImage = document.getElementById('resultImage');
302
- const spinner = document.getElementById('spinner');
303
- const downloadBtn = document.getElementById('downloadBtn');
304
- const errorMessage = document.getElementById('errorMessage');
305
-
306
- let selectedFile = null;
307
-
308
- // Handle file selection
309
- uploadArea.addEventListener('click', () => {
310
- const fileInput = document.createElement('input');
311
- fileInput.type = 'file';
312
- fileInput.accept = 'image/jpeg, image/png';
313
- fileInput.onchange = handleFileSelect;
314
- fileInput.click();
315
- });
316
-
317
- // Handle drag and drop
318
- uploadArea.addEventListener('dragover', (e) => {
319
- e.preventDefault();
320
- uploadArea.classList.add('active');
321
- });
322
-
323
- uploadArea.addEventListener('dragleave', () => {
324
- uploadArea.classList.remove('active');
325
- });
326
-
327
- uploadArea.addEventListener('drop', (e) => {
328
- e.preventDefault();
329
- uploadArea.classList.remove('active');
330
- if (e.dataTransfer.files.length > 0) {
331
- handleFile(e.dataTransfer.files[0]);
332
- }
333
- });
334
-
335
- function handleFileSelect(e) {
336
- if (e.target.files.length > 0) {
337
- handleFile(e.target.files[0]);
338
- }
339
- }
340
-
341
- function handleFile(file) {
342
- if (!file.type.match('image.*')) {
343
- showError('Please select a valid image file (JPG or PNG)');
344
- return;
345
- }
346
-
347
- selectedFile = file;
348
- const reader = new FileReader();
349
-
350
- reader.onload = (e) => {
351
- imagePreview.src = e.target.result;
352
- previewContainer.style.display = 'flex';
353
- document.querySelector('.upload-placeholder').style.opacity = '0';
354
- processBtn.disabled = false;
355
- hideError();
356
- };
357
-
358
- reader.readAsDataURL(file);
359
- }
360
-
361
- // Process image
362
- processBtn.addEventListener('click', () => {
363
- if (!selectedFile) {
364
- showError('Please select an image first');
365
- return;
366
- }
367
-
368
- const objectType = objectTypeInput.value.trim();
369
- if (!objectType) {
370
- showError('Please specify what you want to remove');
371
- return;
372
- }
373
-
374
- showLoading();
375
-
376
- const reader = new FileReader();
377
- reader.onload = (e) => {
378
- const imageData = e.target.result;
379
- processImage(imageData, objectType);
380
- };
381
- reader.readAsDataURL(selectedFile);
382
- });
383
-
384
- function processImage(imageData, objectType) {
385
- fetch('/process', {
386
- method: 'POST',
387
- headers: {
388
- 'Content-Type': 'application/json',
389
- 'X-Requested-With': 'XMLHttpRequest'
390
- },
391
- body: JSON.stringify({
392
- image: imageData,
393
- objectType: objectType
394
- })
395
- })
396
- .then(response => response.json())
397
- .then(data => {
398
- hideLoading();
399
- if (data.success) {
400
- resultImage.src = data.resultPath + '?t=' + new Date().getTime();
401
- resultImage.style.display = 'block';
402
- resultPlaceholder.style.display = 'none';
403
- downloadBtn.style.display = 'flex';
404
- downloadBtn.href = data.resultPath;
405
- } else {
406
- showError(data.message || 'Failed to process image');
407
- }
408
- })
409
- .catch(error => {
410
- hideLoading();
411
- showError('Error processing image. Please try again.');
412
- console.error('Error:', error);
413
- });
414
- }
415
 
416
- function showLoading() {
417
- spinner.style.display = 'block';
418
- resultPlaceholder.style.display = 'none';
419
- resultImage.style.display = 'none';
420
- downloadBtn.style.display = 'none';
421
- processBtn.disabled = true;
422
- }
423
-
424
- function hideLoading() {
425
- spinner.style.display = 'none';
426
- processBtn.disabled = false;
427
- }
428
-
429
- function showError(message) {
430
- errorMessage.textContent = message;
431
- errorMessage.style.display = 'block';
432
- }
433
 
434
- function hideError() {
435
- errorMessage.style.display = 'none';
436
- }
437
- </script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
438
  </body>
439
  </html>
 
1
  <!DOCTYPE html>
2
  <html lang="en">
3
  <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>AI Object Remover</title>
7
+ <link
8
+ href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap"
9
+ rel="stylesheet"
10
+ />
11
+ <link
12
+ rel="stylesheet"
13
+ href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"
14
+ />
15
+ <style>
16
+ :root {
17
+ --primary-color: #6366f1;
18
+ --secondary-color: #4f46e5;
19
+ --accent-color: #8b5cf6;
20
+ --background: #f8fafc;
21
+ --card-bg: #ffffff;
22
+ --text-primary: #1e293b;
23
+ --text-secondary: #64748b;
24
+ --success: #10b981;
25
+ --error: #ef4444;
26
+ }
27
+
28
+ body {
29
+ font-family: 'Poppins', sans-serif;
30
+ background-color: var(--background);
31
+ color: var(--text-primary);
32
+ margin: 0;
33
+ padding: 0;
34
+ min-height: 100vh;
35
+ }
36
+
37
+ .container {
38
+ max-width: 1200px;
39
+ margin: 0 auto;
40
+ padding: 2rem;
41
+ }
42
+
43
+ header {
44
+ text-align: center;
45
+ margin-bottom: 2rem;
46
+ }
47
+
48
+ .logo {
49
+ display: flex;
50
+ align-items: center;
51
+ justify-content: center;
52
+ gap: 1rem;
53
+ margin-bottom: 1rem;
54
+ }
55
+
56
+ .logo i {
57
+ font-size: 2.5rem;
58
+ color: var(--primary-color);
59
+ }
60
+
61
+ h1 {
62
+ font-size: 2.5rem;
63
+ margin: 0;
64
+ background: linear-gradient(to right, var(--primary-color), var(--accent-color));
65
+ -webkit-background-clip: text;
66
+ background-clip: text;
67
+ color: transparent;
68
+ }
69
+
70
+ .subtitle {
71
+ color: var(--text-secondary);
72
+ margin-top: 0.5rem;
73
+ font-weight: 400;
74
+ }
75
+
76
+ .app-container {
77
+ display: grid;
78
+ grid-template-columns: 1fr 1fr;
79
+ gap: 2rem;
80
+ }
81
+
82
+ @media (max-width: 768px) {
83
+ .app-container {
84
+ grid-template-columns: 1fr;
85
+ }
86
+ }
87
+
88
+ .card {
89
+ background-color: var(--card-bg);
90
+ border-radius: 1rem;
91
+ box-shadow: 0 10px 25px rgba(0, 0, 0, 0.05);
92
+ padding: 1.5rem;
93
+ transition: transform 0.3s ease, box-shadow 0.3s ease;
94
+ }
95
+
96
+ .card:hover {
97
+ transform: translateY(-5px);
98
+ box-shadow: 0 15px 35px rgba(0, 0, 0, 0.1);
99
+ }
100
+
101
+ .upload-area {
102
+ border: 2px dashed #d1d5db;
103
+ border-radius: 0.75rem;
104
+ padding: 2rem;
105
+ text-align: center;
106
+ cursor: pointer;
107
+ transition: all 0.3s ease;
108
+ margin-bottom: 1rem;
109
+ position: relative;
110
+ min-height: 200px;
111
+ display: flex;
112
+ align-items: center;
113
+ justify-content: center;
114
+ overflow: hidden;
115
+ }
116
+
117
+ .upload-area:hover {
118
+ border-color: var(--primary-color);
119
+ background-color: rgba(99, 102, 241, 0.05);
120
+ }
121
+
122
+ .upload-placeholder {
123
+ display: flex;
124
+ flex-direction: column;
125
+ align-items: center;
126
+ }
127
+
128
+ .preview-container {
129
+ position: absolute;
130
+ top: 0;
131
+ left: 0;
132
+ width: 100%;
133
+ height: 100%;
134
+ display: none;
135
+ align-items: center;
136
+ justify-content: center;
137
+ background-color: var(--card-bg);
138
+ }
139
+
140
+ .preview-container img {
141
+ max-width: 100%;
142
+ max-height: 100%;
143
+ object-fit: contain;
144
+ }
145
+
146
+ .form-group {
147
+ margin-bottom: 1.5rem;
148
+ }
149
+
150
+ label {
151
+ display: block;
152
+ margin-bottom: 0.5rem;
153
+ font-weight: 500;
154
+ }
155
+
156
+ input[type="text"] {
157
+ width: 100%;
158
+ padding: 0.75rem 1rem;
159
+ border-radius: 0.5rem;
160
+ border: 1px solid #d1d5db;
161
+ font-family: inherit;
162
+ font-size: 1rem;
163
+ transition: border-color 0.3s ease, box-shadow 0.3s ease;
164
+ }
165
+
166
+ input[type="text"]:focus {
167
+ outline: none;
168
+ border-color: var(--primary-color);
169
+ box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.2);
170
+ }
171
+
172
+ .button {
173
+ background-color: var(--primary-color);
174
+ color: white;
175
+ border: none;
176
+ border-radius: 0.5rem;
177
+ padding: 0.75rem 1.5rem;
178
+ font-family: inherit;
179
+ font-size: 1rem;
180
+ font-weight: 500;
181
+ cursor: pointer;
182
+ transition: background-color 0.3s ease, transform 0.2s ease;
183
+ display: flex;
184
+ align-items: center;
185
+ justify-content: center;
186
+ gap: 0.5rem;
187
+ width: 100%;
188
+ }
189
+
190
+ .button:hover {
191
+ background-color: var(--secondary-color);
192
+ transform: translateY(-2px);
193
+ }
194
+
195
+ .button:disabled {
196
+ background-color: #d1d5db;
197
+ cursor: not-allowed;
198
+ }
199
+
200
+ .result-area {
201
+ display: flex;
202
+ flex-direction: column;
203
+ align-items: center;
204
+ justify-content: center;
205
+ text-align: center;
206
+ min-height: 200px;
207
+ position: relative;
208
+ }
209
+
210
+ .result-image {
211
+ max-width: 100%;
212
+ max-height: 300px;
213
+ border-radius: 0.5rem;
214
+ box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
215
+ display: none;
216
+ }
217
+
218
+ .spinner {
219
+ display: none;
220
+ width: 40px;
221
+ height: 40px;
222
+ border: 4px solid rgba(99, 102, 241, 0.1);
223
+ border-left-color: var(--primary-color);
224
+ border-radius: 50%;
225
+ animation: spin 1s linear infinite;
226
+ }
227
+
228
+ .download-btn {
229
+ margin-top: 1rem;
230
+ background-color: var(--success);
231
+ display: none;
232
+ }
233
+
234
+ .error-message {
235
+ color: var(--error);
236
+ margin-top: 1rem;
237
+ display: none;
238
+ text-align: center;
239
+ }
240
+
241
+ @keyframes spin {
242
+ to {
243
+ transform: rotate(360deg);
244
+ }
245
+ }
246
+ </style>
247
  </head>
248
  <body>
249
+ <div class="container">
250
+ <header>
251
+ <div class="logo">
252
+ <i class="fas fa-magic"></i>
253
+ <h1>AI Object Remover</h1>
254
+ </div>
255
+ <p class="subtitle">Remove unwanted objects from your images with AI</p>
256
+ </header>
257
+
258
+ <div class="app-container">
259
+ <div class="card">
260
+ <div class="upload-area" id="uploadArea">
261
+ <div class="upload-placeholder">
262
+ <i class="fas fa-cloud-upload-alt"></i>
263
+ <p>Click or drag & drop your image here</p>
264
+ <span style="font-size: 0.85rem; color: var(--text-secondary);">Supported formats: JPG, PNG</span>
265
+ </div>
266
+ <div class="preview-container" id="previewContainer">
267
+ <img id="imagePreview" src="#" alt="Preview" />
268
+ </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
269
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
270
 
271
+ <div class="form-group">
272
+ <label for="objectType">What do you want to remove?</label>
273
+ <input type="text" id="objectType" placeholder="e.g., person, text, car..." value="text" />
274
+ </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
275
 
276
+ <button id="processBtn" class="button" disabled>
277
+ <i class="fas fa-wand-magic-sparkles"></i>
278
+ <span>Remove Object</span>
279
+ </button>
280
+ <p class="error-message" id="errorMessage"></p>
281
+ </div>
282
+
283
+ <div class="card">
284
+ <div class="result-area">
285
+ <div id="resultPlaceholder">
286
+ <i class="fas fa-image"></i>
287
+ <p>Your edited image will appear here</p>
288
+ </div>
289
+ <div class="spinner" id="spinner"></div>
290
+ <img id="resultImage" class="result-image" src="#" alt="Result" />
291
+ </div>
292
+ <a id="downloadBtn" class="button download-btn" download="edited-image.png">
293
+ <i class="fas fa-download"></i>
294
+ <span>Download Image</span>
295
+ </a>
296
+ </div>
297
+ </div>
298
+ </div>
299
+
300
+ <script>
301
+ const uploadArea = document.getElementById('uploadArea');
302
+ const previewContainer = document.getElementById('previewContainer');
303
+ const imagePreview = document.getElementById('imagePreview');
304
+ const objectTypeInput = document.getElementById('objectType');
305
+ const processBtn = document.getElementById('processBtn');
306
+ const resultPlaceholder = document.getElementById('resultPlaceholder');
307
+ const resultImage = document.getElementById('resultImage');
308
+ const spinner = document.getElementById('spinner');
309
+ const downloadBtn = document.getElementById('downloadBtn');
310
+ const errorMessage = document.getElementById('errorMessage');
311
+
312
+ let selectedFile = null;
313
+
314
+ // Handle file selection
315
+ uploadArea.addEventListener('click', () => {
316
+ const fileInput = document.createElement('input');
317
+ fileInput.type = 'file';
318
+ fileInput.accept = 'image/jpeg, image/png';
319
+ fileInput.onchange = handleFileSelect;
320
+ fileInput.click();
321
+ });
322
+
323
+ // Handle drag and drop
324
+ uploadArea.addEventListener('dragover', (e) => {
325
+ e.preventDefault();
326
+ uploadArea.classList.add('active');
327
+ });
328
+
329
+ uploadArea.addEventListener('dragleave', () => {
330
+ uploadArea.classList.remove('active');
331
+ });
332
+
333
+ uploadArea.addEventListener('drop', (e) => {
334
+ e.preventDefault();
335
+ uploadArea.classList.remove('active');
336
+ if (e.dataTransfer.files.length > 0) {
337
+ handleFile(e.dataTransfer.files[0]);
338
+ }
339
+ });
340
+
341
+ function handleFileSelect(e) {
342
+ if (e.target.files.length > 0) {
343
+ handleFile(e.target.files[0]);
344
+ }
345
+ }
346
+
347
+ function handleFile(file) {
348
+ if (!file.type.match('image.*')) {
349
+ showError('Please select a valid image file (JPG or PNG)');
350
+ return;
351
+ }
352
+ selectedFile = file;
353
+ const reader = new FileReader();
354
+ reader.onload = (e) => {
355
+ imagePreview.src = e.target.result;
356
+ previewContainer.style.display = 'flex';
357
+ document.querySelector('.upload-placeholder').style.opacity = '0';
358
+ processBtn.disabled = false;
359
+ hideError();
360
+ };
361
+ reader.readAsDataURL(file);
362
+ }
363
+
364
+ // Process image
365
+ processBtn.addEventListener('click', () => {
366
+ if (!selectedFile) {
367
+ showError('Please select an image first');
368
+ return;
369
+ }
370
+ const objectType = objectTypeInput.value.trim();
371
+ if (!objectType) {
372
+ showError('Please specify what you want to remove');
373
+ return;
374
+ }
375
+ showLoading();
376
+ const reader = new FileReader();
377
+ reader.onload = (e) => {
378
+ const imageData = e.target.result;
379
+ processImage(imageData, objectType);
380
+ };
381
+ reader.readAsDataURL(selectedFile);
382
+ });
383
+
384
+ function processImage(imageData, objectType) {
385
+ // Replace the URL below with your server endpoint for processing the image.
386
+ fetch('/process', {
387
+ method: 'POST',
388
+ headers: {
389
+ 'Content-Type': 'application/json',
390
+ 'X-Requested-With': 'XMLHttpRequest'
391
+ },
392
+ body: JSON.stringify({
393
+ image: imageData,
394
+ objectType: objectType
395
+ })
396
+ })
397
+ .then(response => response.json())
398
+ .then(data => {
399
+ hideLoading();
400
+ if (data.success) {
401
+ resultImage.src = data.resultPath + '?t=' + new Date().getTime();
402
+ resultImage.style.display = 'block';
403
+ resultPlaceholder.style.display = 'none';
404
+ downloadBtn.style.display = 'flex';
405
+ downloadBtn.href = data.resultPath;
406
+ } else {
407
+ showError(data.message || 'Failed to process image');
408
+ }
409
+ })
410
+ .catch(error => {
411
+ hideLoading();
412
+ showError('Error processing image. Please try again.');
413
+ console.error('Error:', error);
414
+ });
415
+ }
416
+
417
+ function showLoading() {
418
+ spinner.style.display = 'block';
419
+ resultPlaceholder.style.display = 'none';
420
+ resultImage.style.display = 'none';
421
+ downloadBtn.style.display = 'none';
422
+ processBtn.disabled = true;
423
+ }
424
+
425
+ function hideLoading() {
426
+ spinner.style.display = 'none';
427
+ processBtn.disabled = false;
428
+ }
429
+
430
+ function showError(message) {
431
+ errorMessage.textContent = message;
432
+ errorMessage.style.display = 'block';
433
+ }
434
+
435
+ function hideError() {
436
+ errorMessage.style.display = 'none';
437
+ }
438
+ </script>
439
  </body>
440
  </html>