savvysmith commited on
Commit
16565ce
·
verified ·
1 Parent(s): 5018dc2

it does not show an image - Initial Deployment

Browse files
Files changed (2) hide show
  1. README.md +7 -5
  2. index.html +945 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Wigapp
3
- emoji: 🐨
4
- colorFrom: pink
5
- colorTo: indigo
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: wigapp
3
+ emoji: 🐳
4
+ colorFrom: gray
5
+ colorTo: pink
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,945 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </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>HairFastGAN Wig Try-On</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
+ <style>
10
+ .camera-container {
11
+ position: relative;
12
+ width: 100%;
13
+ height: 0;
14
+ padding-bottom: 75%;
15
+ background-color: #f3f4f6;
16
+ border-radius: 0.5rem;
17
+ overflow: hidden;
18
+ }
19
+
20
+ .camera-video {
21
+ position: absolute;
22
+ top: 0;
23
+ left: 0;
24
+ width: 100%;
25
+ height: 100%;
26
+ object-fit: cover;
27
+ }
28
+
29
+ .camera-controls {
30
+ position: absolute;
31
+ bottom: 1rem;
32
+ left: 0;
33
+ width: 100%;
34
+ display: flex;
35
+ justify-content: center;
36
+ gap: 1rem;
37
+ }
38
+
39
+ .gallery-item {
40
+ transition: all 0.2s ease;
41
+ }
42
+
43
+ .gallery-item:hover {
44
+ transform: scale(1.05);
45
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
46
+ }
47
+
48
+ .gallery-item.selected {
49
+ border: 3px solid #6366f1;
50
+ transform: scale(1.05);
51
+ }
52
+
53
+ .result-container {
54
+ position: relative;
55
+ transition: all 0.3s ease;
56
+ }
57
+
58
+ .result-container.loading::after {
59
+ content: "";
60
+ position: absolute;
61
+ top: 0;
62
+ left: 0;
63
+ width: 100%;
64
+ height: 100%;
65
+ background-color: rgba(0, 0, 0, 0.5);
66
+ display: flex;
67
+ justify-content: center;
68
+ align-items: center;
69
+ color: white;
70
+ font-size: 1.5rem;
71
+ }
72
+
73
+ .loading-spinner {
74
+ width: 50px;
75
+ height: 50px;
76
+ border: 5px solid #f3f3f3;
77
+ border-top: 5px solid #6366f1;
78
+ border-radius: 50%;
79
+ animation: spin 1s linear infinite;
80
+ margin: 0 auto;
81
+ }
82
+
83
+ @keyframes spin {
84
+ 0% { transform: rotate(0deg); }
85
+ 100% { transform: rotate(360deg); }
86
+ }
87
+
88
+ .color-picker {
89
+ -webkit-appearance: none;
90
+ -moz-appearance: none;
91
+ appearance: none;
92
+ width: 100%;
93
+ height: 40px;
94
+ background-color: transparent;
95
+ border: none;
96
+ cursor: pointer;
97
+ }
98
+
99
+ .color-picker::-webkit-color-swatch {
100
+ border-radius: 8px;
101
+ border: 2px solid #e5e7eb;
102
+ }
103
+
104
+ .color-picker::-moz-color-swatch {
105
+ border-radius: 8px;
106
+ border: 2px solid #e5e7eb;
107
+ }
108
+
109
+ .tab-content {
110
+ display: none;
111
+ }
112
+
113
+ .tab-content.active {
114
+ display: block;
115
+ }
116
+
117
+ .progress-bar {
118
+ height: 6px;
119
+ background-color: #e5e7eb;
120
+ border-radius: 3px;
121
+ overflow: hidden;
122
+ }
123
+
124
+ .progress-fill {
125
+ height: 100%;
126
+ background-color: #6366f1;
127
+ width: 0%;
128
+ transition: width 0.3s ease;
129
+ }
130
+
131
+ .processing-step {
132
+ display: flex;
133
+ align-items: center;
134
+ margin-bottom: 0.5rem;
135
+ color: #6b7280;
136
+ }
137
+
138
+ .processing-step.active {
139
+ color: #111827;
140
+ font-weight: 500;
141
+ }
142
+
143
+ .processing-step.completed {
144
+ color: #10b981;
145
+ }
146
+
147
+ .processing-step i {
148
+ margin-right: 0.5rem;
149
+ }
150
+ </style>
151
+ </head>
152
+ <body class="bg-gray-50 min-h-screen">
153
+ <div class="container mx-auto px-4 py-8">
154
+ <header class="mb-8">
155
+ <div class="flex justify-between items-center">
156
+ <div>
157
+ <h1 class="text-3xl font-bold text-indigo-600">HairFastGAN</h1>
158
+ <p class="text-gray-600">AI-Powered Virtual Wig Try-On</p>
159
+ </div>
160
+ <div class="flex items-center space-x-4">
161
+ <button id="loginBtn" class="px-4 py-2 text-gray-600 hover:text-indigo-600">
162
+ <i class="fas fa-user mr-2"></i>Login
163
+ </button>
164
+ <button id="creditsBtn" class="px-4 py-2 bg-indigo-100 text-indigo-600 rounded-full hover:bg-indigo-200">
165
+ <i class="fas fa-coins mr-2"></i>5 Credits
166
+ </button>
167
+ </div>
168
+ </div>
169
+ </header>
170
+
171
+ <div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
172
+ <!-- Left Column - Input Section -->
173
+ <div class="lg:col-span-2 bg-white rounded-xl shadow-md p-6">
174
+ <div class="flex border-b border-gray-200 mb-6">
175
+ <button class="tab-btn active px-4 py-2 font-medium text-indigo-600 border-b-2 border-indigo-600" data-tab="upload">
176
+ <i class="fas fa-upload mr-2"></i>Upload Photo
177
+ </button>
178
+ <button class="tab-btn px-4 py-2 font-medium text-gray-500 hover:text-indigo-600" data-tab="camera">
179
+ <i class="fas fa-camera mr-2"></i>Live Camera
180
+ </button>
181
+ </div>
182
+
183
+ <!-- Upload Tab -->
184
+ <div id="upload" class="tab-content active">
185
+ <div class="mb-6">
186
+ <h3 class="text-lg font-medium text-gray-900 mb-2">Upload Your Photo</h3>
187
+ <p class="text-gray-500 mb-4">For best results, use a clear front-facing photo with good lighting.</p>
188
+ <div class="flex flex-col items-center justify-center border-2 border-dashed border-gray-300 rounded-lg p-8 bg-gray-50">
189
+ <i class="fas fa-cloud-upload-alt text-4xl text-gray-400 mb-3"></i>
190
+ <p class="text-gray-500 mb-3">Drag & drop your photo here</p>
191
+ <p class="text-gray-400 text-sm mb-4">or</p>
192
+ <input type="file" id="photoUpload" accept="image/*" class="hidden">
193
+ <button id="uploadBtn" class="px-4 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700">
194
+ <i class="fas fa-folder-open mr-2"></i>Browse Files
195
+ </button>
196
+ </div>
197
+ <div id="uploadPreview" class="mt-4 hidden">
198
+ <h4 class="text-md font-medium text-gray-900 mb-2">Preview</h4>
199
+ <div class="relative">
200
+ <img id="uploadedImage" src="" alt="Uploaded photo" class="w-full h-auto rounded-lg max-h-96 object-contain">
201
+ <button id="removeUpload" class="absolute top-2 right-2 bg-white p-2 rounded-full shadow-md hover:bg-gray-100">
202
+ <i class="fas fa-times text-gray-700"></i>
203
+ </button>
204
+ </div>
205
+ </div>
206
+ </div>
207
+ </div>
208
+
209
+ <!-- Camera Tab -->
210
+ <div id="camera" class="tab-content">
211
+ <div class="mb-6">
212
+ <h3 class="text-lg font-medium text-gray-900 mb-2">Live Camera Try-On</h3>
213
+ <p class="text-gray-500 mb-4">Allow camera access to try wigs in real-time.</p>
214
+ <div class="camera-container">
215
+ <video id="cameraVideo" class="camera-video" autoplay playsinline></video>
216
+ <div class="camera-controls">
217
+ <button id="captureBtn" class="p-3 bg-indigo-600 text-white rounded-full hover:bg-indigo-700">
218
+ <i class="fas fa-camera text-xl"></i>
219
+ </button>
220
+ </div>
221
+ </div>
222
+ <div id="capturePreview" class="mt-4 hidden">
223
+ <h4 class="text-md font-medium text-gray-900 mb-2">Captured Photo</h4>
224
+ <div class="relative">
225
+ <canvas id="capturedImage" class="w-full h-auto rounded-lg max-h-96 object-contain"></canvas>
226
+ <button id="retakeBtn" class="absolute top-2 right-2 bg-white p-2 rounded-full shadow-md hover:bg-gray-100">
227
+ <i class="fas fa-redo text-gray-700"></i>
228
+ </button>
229
+ </div>
230
+ </div>
231
+ </div>
232
+ </div>
233
+
234
+ <!-- Hairstyle Selection -->
235
+ <div class="mb-6">
236
+ <h3 class="text-lg font-medium text-gray-900 mb-2">Choose Your Wig Style</h3>
237
+ <div class="flex border-b border-gray-200 mb-4">
238
+ <button class="style-tab-btn px-4 py-2 font-medium text-gray-500 hover:text-indigo-600" data-style="gallery">
239
+ <i class="fas fa-images mr-2"></i>Style Gallery
240
+ </button>
241
+ <button class="style-tab-btn px-4 py-2 font-medium text-gray-500 hover:text-indigo-600" data-style="color">
242
+ <i class="fas fa-palette mr-2"></i>Color Only
243
+ </button>
244
+ <button class="style-tab-btn active px-4 py-2 font-medium text-indigo-600 border-b-2 border-indigo-600" data-style="upload">
245
+ <i class="fas fa-upload mr-2"></i>Upload Your Wig
246
+ </button>
247
+ </div>
248
+
249
+ <!-- Style Gallery -->
250
+ <div id="gallery" class="style-tab-content active">
251
+ <div class="mb-4">
252
+ <div class="flex overflow-x-auto pb-2 space-x-3">
253
+ <button class="category-btn active px-3 py-1 bg-indigo-600 text-white rounded-full text-sm" data-category="all">All</button>
254
+ <button class="category-btn px-3 py-1 bg-gray-200 text-gray-700 rounded-full text-sm hover:bg-gray-300" data-category="short">Short</button>
255
+ <button class="category-btn px-3 py-1 bg-gray-200 text-gray-700 rounded-full text-sm hover:bg-gray-300" data-category="medium">Medium</button>
256
+ <button class="category-btn px-3 py-1 bg-gray-200 text-gray-700 rounded-full text-sm hover:bg-gray-300" data-category="long">Long</button>
257
+ <button class="category-btn px-3 py-1 bg-gray-200 text-gray-700 rounded-full text-sm hover:bg-gray-300" data-category="curly">Curly</button>
258
+ <button class="category-btn px-3 py-1 bg-gray-200 text-gray-700 rounded-full text-sm hover:bg-gray-300" data-category="straight">Straight</button>
259
+ <button class="category-btn px-3 py-1 bg-gray-200 text-gray-700 rounded-full text-sm hover:bg-gray-300" data-category="vip" data-vip="true">
260
+ <i class="fas fa-crown mr-1 text-yellow-500"></i>VIP
261
+ </button>
262
+ </div>
263
+ </div>
264
+ <div class="grid grid-cols-3 sm:grid-cols-4 md:grid-cols-5 gap-3">
265
+ <!-- Sample wig styles - in a real app these would come from a database -->
266
+ <div class="gallery-item rounded-lg overflow-hidden cursor-pointer" data-id="1" data-category="short straight">
267
+ <img src="/wigs/short-bob.jpg" alt="Short straight wig" class="w-full h-24 object-cover">
268
+ <div class="p-2 text-center text-xs">Short Bob</div>
269
+ </div>
270
+ <div class="gallery-item rounded-lg overflow-hidden cursor-pointer" data-id="2" data-category="medium curly">
271
+ <img src="/wigs/curly-shoulder.jpg" alt="Medium curly wig" class="w-full h-24 object-cover">
272
+ <div class="p-2 text-center text-xs">Curly Shoulder</div>
273
+ </div>
274
+ <div class="gallery-item rounded-lg overflow-hidden cursor-pointer" data-id="3" data-category="long straight">
275
+ <img src="/wigs/long-straight.jpg" alt="Long straight wig" class="w-full h-24 object-cover">
276
+ <div class="p-2 text-center text-xs">Long Straight</div>
277
+ </div>
278
+ <div class="gallery-item rounded-lg overflow-hidden cursor-pointer" data-id="4" data-category="short curly">
279
+ <img src="/wigs/short-curly.jpg" alt="Short curly wig" class="w-full h-24 object-cover">
280
+ <div class="p-2 text-center text-xs">Short Curly</div>
281
+ </div>
282
+ <div class="gallery-item rounded-lg overflow-hidden cursor-pointer" data-id="5" data-category="medium straight">
283
+ <img src="/wigs/medium-straight.jpg" alt="Medium straight wig" class="w-full h-24 object-cover">
284
+ <div class="p-2 text-center text-xs">Medium Straight</div>
285
+ </div>
286
+ <div class="gallery-item rounded-lg overflow-hidden cursor-pointer" data-id="6" data-category="long curly">
287
+ <img src="/wigs/long-curly.jpg" alt="Long curly wig" class="w-full h-24 object-cover">
288
+ <div class="p-2 text-center text-xs">Long Curly</div>
289
+ </div>
290
+ <div class="gallery-item rounded-lg overflow-hidden cursor-pointer" data-id="7" data-category="vip long straight" data-vip="true">
291
+ <img src="/wigs/vip-ombre.jpg" alt="VIP long straight wig" class="w-full h-24 object-cover">
292
+ <div class="p-2 text-center text-xs flex items-center justify-center">
293
+ <span>VIP Ombre</span>
294
+ <i class="fas fa-crown ml-1 text-yellow-500"></i>
295
+ </div>
296
+ </div>
297
+ <div class="gallery-item rounded-lg overflow-hidden cursor-pointer" data-id="8" data-category="vip medium curly" data-vip="true">
298
+ <img src="/wigs/vip-waves.jpg" alt="VIP medium curly wig" class="w-full h-24 object-cover">
299
+ <div class="p-2 text-center text-xs flex items-center justify-center">
300
+ <span>VIP Waves</span>
301
+ <i class="fas fa-crown ml-1 text-yellow-500"></i>
302
+ </div>
303
+ </div>
304
+ </div>
305
+ </div>
306
+
307
+ <!-- Color Only -->
308
+ <div id="color" class="style-tab-content">
309
+ <div class="mb-4">
310
+ <p class="text-gray-500 mb-3">Select a hair color to apply to your current hairstyle:</p>
311
+ <input type="color" id="hairColorPicker" class="color-picker" value="#5a3e2a">
312
+ </div>
313
+ <div class="grid grid-cols-5 gap-3">
314
+ <div class="color-swatch bg-[#000000] h-10 rounded cursor-pointer" data-color="#000000"></div>
315
+ <div class="color-swatch bg-[#5a3e2a] h-10 rounded cursor-pointer" data-color="#5a3e2a"></div>
316
+ <div class="color-swatch bg-[#a55728] h-10 rounded cursor-pointer" data-color="#a55728"></div>
317
+ <div class="color-swatch bg-[#b58143] h-10 rounded cursor-pointer" data-color="#b58143"></div>
318
+ <div class="color-swatch bg-[#d4b996] h-10 rounded cursor-pointer" data-color="#d4b996"></div>
319
+ <div class="color-swatch bg-[#f0e2c6] h-10 rounded cursor-pointer" data-color="#f0e2c6"></div>
320
+ <div class="color-swatch bg-[#c93384] h-10 rounded cursor-pointer" data-color="#c93384"></div>
321
+ <div class="color-swatch bg-[#e64980] h-10 rounded cursor-pointer" data-color="#e64980"></div>
322
+ <div class="color-swatch bg-[#6741d9] h-10 rounded cursor-pointer" data-color="#6741d9"></div>
323
+ <div class="color-swatch bg-[#228be6] h-10 rounded cursor-pointer" data-color="#228be6"></div>
324
+ </div>
325
+ </div>
326
+
327
+ <!-- Upload Style -->
328
+ <div id="uploadStyle" class="style-tab-content active">
329
+ <div class="mb-4">
330
+ <p class="text-gray-500 mb-3">Upload a photo of the wig you want to try on:</p>
331
+ <div class="flex flex-col items-center justify-center border-2 border-dashed border-gray-300 rounded-lg p-8 bg-gray-50 hover:bg-gray-100 transition-colors duration-200">
332
+ <i class="fas fa-wig text-4xl text-indigo-400 mb-3"></i>
333
+ <p class="text-gray-500 mb-3 font-medium">Drag & drop wig photo here</p>
334
+ <p class="text-gray-400 text-sm mb-4">or</p>
335
+ <input type="file" id="styleUpload" accept="image/*" class="hidden">
336
+ <button id="uploadStyleBtn" class="px-6 py-3 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition-colors duration-200">
337
+ <i class="fas fa-upload mr-2"></i>Select Wig Image
338
+ </button>
339
+ <p class="text-gray-400 text-xs mt-3">Supports JPG, PNG up to 5MB</p>
340
+ </div>
341
+ </div>
342
+ <div id="stylePreview" class="hidden mt-6">
343
+ <h4 class="text-lg font-medium text-gray-900 mb-3">Your Selected Wig</h4>
344
+ <div class="relative bg-gray-100 rounded-xl p-4">
345
+ <img id="uploadedStyleImage" src="" alt="Uploaded wig" class="w-full h-auto rounded-lg max-h-64 object-contain mx-auto">
346
+ <button id="removeStyle" class="absolute top-4 right-4 bg-white p-2 rounded-full shadow-md hover:bg-gray-100 transition-colors duration-200">
347
+ <i class="fas fa-redo text-gray-700"></i> Change
348
+ </button>
349
+ </div>
350
+ <div class="mt-4 flex items-center justify-between">
351
+ <div>
352
+ <h5 class="font-medium">Wig Details</h5>
353
+ <p id="wigDetails" class="text-sm text-gray-500">Uploaded wig</p>
354
+ </div>
355
+ <button id="analyzeWigBtn" class="px-4 py-2 bg-indigo-100 text-indigo-700 rounded-lg hover:bg-indigo-200 transition-colors duration-200">
356
+ <i class="fas fa-search mr-2"></i> Analyze Wig
357
+ </button>
358
+ </div>
359
+ </div>
360
+ </div>
361
+ </div>
362
+
363
+ <!-- Processing Options -->
364
+ <div class="mb-6">
365
+ <h3 class="text-lg font-medium text-gray-900 mb-2">Processing Options</h3>
366
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
367
+ <div>
368
+ <label class="flex items-center">
369
+ <input type="checkbox" class="rounded text-indigo-600" checked>
370
+ <span class="ml-2 text-gray-700">Pose Alignment (Rotate Encoder)</span>
371
+ </label>
372
+ <p class="text-gray-500 text-sm ml-6">Adjusts head position for better matching</p>
373
+ </div>
374
+ <div>
375
+ <label class="flex items-center">
376
+ <input type="checkbox" class="rounded text-indigo-600" checked>
377
+ <span class="ml-2 text-gray-700">Shape Alignment (SEAN + StyleGAN)</span>
378
+ </label>
379
+ <p class="text-gray-500 text-sm ml-6">Matches the wig shape to your face</p>
380
+ </div>
381
+ <div>
382
+ <label class="flex items-center">
383
+ <input type="checkbox" class="rounded text-indigo-600" checked>
384
+ <span class="ml-2 text-gray-700">Color Alignment (CLIP-guided S editing)</span>
385
+ </label>
386
+ <p class="text-gray-500 text-sm ml-6">Ensures natural-looking color transfer</p>
387
+ </div>
388
+ <div>
389
+ <label class="flex items-center">
390
+ <input type="checkbox" class="rounded text-indigo-600" checked>
391
+ <span class="ml-2 text-gray-700">Detail Refinement (64x64 FS fusion)</span>
392
+ </label>
393
+ <p class="text-gray-500 text-sm ml-6">Restores facial identity and details</p>
394
+ </div>
395
+ </div>
396
+ </div>
397
+
398
+ <button id="generateBtn" class="w-full py-3 bg-indigo-600 text-white rounded-lg font-medium hover:bg-indigo-700 flex items-center justify-center">
399
+ <i class="fas fa-magic mr-2"></i>Generate Wig Try-On (1 Credit)
400
+ </button>
401
+ </div>
402
+
403
+ <!-- Right Column - Results Section -->
404
+ <div class="bg-white rounded-xl shadow-md p-6">
405
+ <h2 class="text-xl font-bold text-gray-900 mb-4">Your Results</h2>
406
+
407
+ <div id="emptyState" class="flex flex-col items-center justify-center py-12">
408
+ <i class="fas fa-cut text-5xl text-gray-300 mb-4"></i>
409
+ <h3 class="text-lg font-medium text-gray-700 mb-2">No results yet</h3>
410
+ <p class="text-gray-500 text-center mb-4">Upload your photo and select a wig style to see how it would look on you!</p>
411
+ </div>
412
+
413
+ <div id="resultContainer" class="hidden">
414
+ <div class="result-container mb-4">
415
+ <img id="resultImage" src="" alt="Wig try-on result" class="w-full h-auto rounded-lg">
416
+ </div>
417
+
418
+ <div class="flex justify-between mb-4">
419
+ <div>
420
+ <h4 class="font-medium text-gray-900">Your Selected Style</h4>
421
+ <p id="selectedStyleName" class="text-gray-500 text-sm">Short Bob</p>
422
+ </div>
423
+ <div class="flex space-x-2">
424
+ <button id="downloadBtn" class="p-2 bg-gray-100 rounded-full hover:bg-gray-200">
425
+ <i class="fas fa-download text-gray-700"></i>
426
+ </button>
427
+ <button id="saveBtn" class="p-2 bg-gray-100 rounded-full hover:bg-gray-200">
428
+ <i class="fas fa-save text-gray-700"></i>
429
+ </button>
430
+ <button id="shareBtn" class="p-2 bg-gray-100 rounded-full hover:bg-gray-200">
431
+ <i class="fas fa-share-alt text-gray-700"></i>
432
+ </button>
433
+ </div>
434
+ </div>
435
+
436
+ <div class="mb-6">
437
+ <h4 class="font-medium text-gray-900 mb-2">Try Another Style</h4>
438
+ <div class="grid grid-cols-4 gap-2">
439
+ <div class="rounded overflow-hidden cursor-pointer">
440
+ <img src="/wigs/short-bob-thumb.jpg" alt="Short straight wig" class="w-full h-16 object-cover">
441
+ </div>
442
+ <div class="rounded overflow-hidden cursor-pointer">
443
+ <img src="/wigs/curly-shoulder-thumb.jpg" alt="Medium curly wig" class="w-full h-16 object-cover">
444
+ </div>
445
+ <div class="rounded overflow-hidden cursor-pointer">
446
+ <img src="/wigs/long-straight-thumb.jpg" alt="Long straight wig" class="w-full h-16 object-cover">
447
+ </div>
448
+ <div class="rounded overflow-hidden cursor-pointer">
449
+ <img src="/wigs/short-curly-thumb.jpg" alt="Short curly wig" class="w-full h-16 object-cover">
450
+ </div>
451
+ </div>
452
+ </div>
453
+
454
+ <div class="bg-indigo-50 rounded-lg p-4">
455
+ <h4 class="font-medium text-indigo-800 mb-2">Love this style?</h4>
456
+ <p class="text-indigo-700 text-sm mb-3">Get this exact wig customized to your measurements.</p>
457
+ <button id="buyBtn" class="w-full py-2 bg-indigo-600 text-white rounded-lg text-sm font-medium hover:bg-indigo-700">
458
+ Order Custom Wig ($89.99)
459
+ </button>
460
+ </div>
461
+ </div>
462
+
463
+ <div id="processingContainer" class="hidden">
464
+ <div class="flex flex-col items-center justify-center py-8">
465
+ <div class="loading-spinner mb-4"></div>
466
+ <h3 class="text-lg font-medium text-gray-900 mb-2">Processing Your Image</h3>
467
+ <p class="text-gray-500 text-center mb-6">Our AI is applying your selected wig style...</p>
468
+
469
+ <div class="w-full mb-6">
470
+ <div class="progress-bar">
471
+ <div id="progressFill" class="progress-fill"></div>
472
+ </div>
473
+ </div>
474
+
475
+ <div class="w-full space-y-2">
476
+ <div class="processing-step active">
477
+ <i class="fas fa-sync-alt"></i>
478
+ <span>Pose alignment using Rotate Encoder</span>
479
+ </div>
480
+ <div class="processing-step">
481
+ <i class="fas fa-project-diagram"></i>
482
+ <span>Shape alignment in FS space</span>
483
+ </div>
484
+ <div class="processing-step">
485
+ <i class="fas fa-palette"></i>
486
+ <span>Color alignment with CLIP guidance</span>
487
+ </div>
488
+ <div class="processing-step">
489
+ <i class="fas fa-magic"></i>
490
+ <span>Detail refinement with 64x64 FS fusion</span>
491
+ </div>
492
+ <div class="processing-step">
493
+ <i class="fas fa-check-circle"></i>
494
+ <span>Final rendering</span>
495
+ </div>
496
+ </div>
497
+ </div>
498
+ </div>
499
+ </div>
500
+ </div>
501
+
502
+ <!-- VIP Modal -->
503
+ <div id="vipModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden">
504
+ <div class="bg-white rounded-xl p-6 max-w-md w-full">
505
+ <div class="flex justify-between items-center mb-4">
506
+ <h3 class="text-xl font-bold text-gray-900">VIP Styles</h3>
507
+ <button id="closeVipModal" class="text-gray-500 hover:text-gray-700">
508
+ <i class="fas fa-times"></i>
509
+ </button>
510
+ </div>
511
+ <div class="mb-4">
512
+ <p class="text-gray-600">VIP styles are premium designs that require additional credits to unlock.</p>
513
+ </div>
514
+ <div class="bg-yellow-50 border border-yellow-200 rounded-lg p-4 mb-4">
515
+ <div class="flex">
516
+ <div class="flex-shrink-0">
517
+ <i class="fas fa-crown text-yellow-500 mt-1"></i>
518
+ </div>
519
+ <div class="ml-3">
520
+ <h3 class="text-sm font-medium text-yellow-800">VIP Style Detected</h3>
521
+ <div class="mt-2 text-sm text-yellow-700">
522
+ <p>This style requires 3 credits to try on.</p>
523
+ </div>
524
+ </div>
525
+ </div>
526
+ </div>
527
+ <div class="grid grid-cols-2 gap-4">
528
+ <button id="useCreditsBtn" class="py-2 bg-indigo-600 text-white rounded-lg font-medium hover:bg-indigo-700">
529
+ Use 3 Credits
530
+ </button>
531
+ <button id="buyCreditsBtn" class="py-2 bg-yellow-500 text-white rounded-lg font-medium hover:bg-yellow-600">
532
+ Buy More Credits
533
+ </button>
534
+ </div>
535
+ </div>
536
+ </div>
537
+
538
+ <!-- Credits Modal -->
539
+ <div id="creditsModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden">
540
+ <div class="bg-white rounded-xl p-6 max-w-md w-full">
541
+ <div class="flex justify-between items-center mb-4">
542
+ <h3 class="text-xl font-bold text-gray-900">Buy More Credits</h3>
543
+ <button id="closeCreditsModal" class="text-gray-500 hover:text-gray-700">
544
+ <i class="fas fa-times"></i>
545
+ </button>
546
+ </div>
547
+ <div class="mb-4">
548
+ <p class="text-gray-600">Each credit allows you to generate one wig try-on result.</p>
549
+ </div>
550
+ <div class="space-y-3 mb-6">
551
+ <div class="flex items-center justify-between p-3 border border-gray-200 rounded-lg hover:border-indigo-300">
552
+ <div>
553
+ <h4 class="font-medium text-gray-900">10 Credits</h4>
554
+ <p class="text-sm text-gray-500">$9.99 ($1.00 per credit)</p>
555
+ </div>
556
+ <button class="px-4 py-2 bg-indigo-600 text-white rounded-lg text-sm font-medium hover:bg-indigo-700">
557
+ Select
558
+ </button>
559
+ </div>
560
+ <div class="flex items-center justify-between p-3 border border-gray-200 rounded-lg hover:border-indigo-300">
561
+ <div>
562
+ <h4 class="font-medium text-gray-900">25 Credits</h4>
563
+ <p class="text-sm text-gray-500">$19.99 ($0.80 per credit)</p>
564
+ </div>
565
+ <button class="px-4 py-2 bg-indigo-600 text-white rounded-lg text-sm font-medium hover:bg-indigo-700">
566
+ Select
567
+ </button>
568
+ </div>
569
+ <div class="flex items-center justify-between p-3 border border-gray-200 rounded-lg hover:border-indigo-300 bg-indigo-50 border-indigo-200">
570
+ <div>
571
+ <h4 class="font-medium text-indigo-900">50 Credits</h4>
572
+ <p class="text-sm text-indigo-700">$29.99 ($0.60 per credit)</p>
573
+ </div>
574
+ <div class="flex items-center">
575
+ <span class="bg-indigo-600 text-white text-xs font-medium px-2 py-0.5 rounded mr-2">Best Value</span>
576
+ <button class="px-4 py-2 bg-indigo-600 text-white rounded-lg text-sm font-medium hover:bg-indigo-700">
577
+ Select
578
+ </button>
579
+ </div>
580
+ </div>
581
+ </div>
582
+ <div class="text-center">
583
+ <button id="subscribeBtn" class="text-indigo-600 hover:text-indigo-800 text-sm font-medium">
584
+ Or subscribe for unlimited credits at $14.99/month
585
+ </button>
586
+ </div>
587
+ </div>
588
+ </div>
589
+ </div>
590
+
591
+ <script>
592
+ // DOM Elements
593
+ const tabBtns = document.querySelectorAll('.tab-btn');
594
+ const tabContents = document.querySelectorAll('.tab-content');
595
+ const styleTabBtns = document.querySelectorAll('.style-tab-btn');
596
+ const styleTabContents = document.querySelectorAll('.style-tab-content');
597
+ const categoryBtns = document.querySelectorAll('.category-btn');
598
+ const galleryItems = document.querySelectorAll('.gallery-item');
599
+ const colorSwatches = document.querySelectorAll('.color-swatch');
600
+ const uploadBtn = document.getElementById('uploadBtn');
601
+ const photoUpload = document.getElementById('photoUpload');
602
+ const uploadPreview = document.getElementById('uploadPreview');
603
+ const uploadedImage = document.getElementById('uploadedImage');
604
+ const removeUpload = document.getElementById('removeUpload');
605
+ const generateBtn = document.getElementById('generateBtn');
606
+ const emptyState = document.getElementById('emptyState');
607
+ const resultContainer = document.getElementById('resultContainer');
608
+ const resultImage = document.getElementById('resultImage');
609
+ const processingContainer = document.getElementById('processingContainer');
610
+ const progressFill = document.getElementById('progressFill');
611
+ const processingSteps = document.querySelectorAll('.processing-step');
612
+ const vipModal = document.getElementById('vipModal');
613
+ const closeVipModal = document.getElementById('closeVipModal');
614
+ const useCreditsBtn = document.getElementById('useCreditsBtn');
615
+ const buyCreditsBtn = document.getElementById('buyCreditsBtn');
616
+ const creditsBtn = document.getElementById('creditsBtn');
617
+ const creditsModal = document.getElementById('creditsModal');
618
+ const closeCreditsModal = document.getElementById('closeCreditsModal');
619
+ const captureBtn = document.getElementById('captureBtn');
620
+ const cameraVideo = document.getElementById('cameraVideo');
621
+ const capturedImage = document.getElementById('capturedImage');
622
+ const capturePreview = document.getElementById('capturePreview');
623
+ const retakeBtn = document.getElementById('retakeBtn');
624
+ const uploadStyleBtn = document.getElementById('uploadStyleBtn');
625
+ const styleUpload = document.getElementById('styleUpload');
626
+ const stylePreview = document.getElementById('stylePreview');
627
+ const uploadedStyleImage = document.getElementById('uploadedStyleImage');
628
+ const removeStyle = document.getElementById('removeStyle');
629
+ const hairColorPicker = document.getElementById('hairColorPicker');
630
+ const selectedStyleName = document.getElementById('selectedStyleName');
631
+
632
+ // Tab switching
633
+ tabBtns.forEach(btn => {
634
+ btn.addEventListener('click', () => {
635
+ tabBtns.forEach(b => b.classList.remove('active', 'text-indigo-600', 'border-indigo-600'));
636
+ btn.classList.add('active', 'text-indigo-600', 'border-indigo-600');
637
+
638
+ const tabId = btn.getAttribute('data-tab');
639
+ tabContents.forEach(content => {
640
+ content.classList.remove('active');
641
+ if (content.id === tabId) {
642
+ content.classList.add('active');
643
+
644
+ // Initialize camera if camera tab is selected
645
+ if (tabId === 'camera') {
646
+ initCamera();
647
+ } else {
648
+ stopCamera();
649
+ }
650
+ }
651
+ });
652
+ });
653
+ });
654
+
655
+ // Style tab switching
656
+ styleTabBtns.forEach(btn => {
657
+ btn.addEventListener('click', () => {
658
+ styleTabBtns.forEach(b => b.classList.remove('active', 'text-indigo-600', 'border-indigo-600'));
659
+ btn.classList.add('active', 'text-indigo-600', 'border-indigo-600');
660
+
661
+ const styleTabId = btn.getAttribute('data-style');
662
+ styleTabContents.forEach(content => {
663
+ content.classList.remove('active');
664
+ if (content.id === styleTabId) {
665
+ content.classList.add('active');
666
+ }
667
+ });
668
+ });
669
+ });
670
+
671
+ // Category filtering
672
+ categoryBtns.forEach(btn => {
673
+ btn.addEventListener('click', () => {
674
+ categoryBtns.forEach(b => b.classList.remove('active', 'bg-indigo-600', 'text-white'));
675
+ btn.classList.add('active', 'bg-indigo-600', 'text-white');
676
+
677
+ const category = btn.getAttribute('data-category');
678
+ const isVip = btn.getAttribute('data-vip') === 'true';
679
+
680
+ galleryItems.forEach(item => {
681
+ const itemCategories = item.getAttribute('data-category').split(' ');
682
+ const itemIsVip = item.getAttribute('data-vip') === 'true';
683
+
684
+ if (category === 'all' ||
685
+ itemCategories.includes(category) ||
686
+ (isVip && itemIsVip)) {
687
+ item.style.display = 'block';
688
+ } else {
689
+ item.style.display = 'none';
690
+ }
691
+ });
692
+ });
693
+ });
694
+
695
+ // Gallery item selection
696
+ galleryItems.forEach(item => {
697
+ item.addEventListener('click', () => {
698
+ // Check if VIP style
699
+ const isVip = item.getAttribute('data-vip') === 'true';
700
+
701
+ if (isVip) {
702
+ // Show VIP modal
703
+ vipModal.classList.remove('hidden');
704
+ return;
705
+ }
706
+
707
+ galleryItems.forEach(i => i.classList.remove('selected'));
708
+ item.classList.add('selected');
709
+
710
+ // Update selected style name
711
+ const styleName = item.querySelector('div').textContent.trim();
712
+ selectedStyleName.textContent = styleName;
713
+ });
714
+ });
715
+
716
+ // Color swatch selection
717
+ colorSwatches.forEach(swatch => {
718
+ swatch.addEventListener('click', () => {
719
+ const color = swatch.getAttribute('data-color');
720
+ hairColorPicker.value = color;
721
+
722
+ // Highlight selected swatch
723
+ colorSwatches.forEach(s => s.classList.remove('ring-2', 'ring-indigo-500', 'ring-offset-2'));
724
+ swatch.classList.add('ring-2', 'ring-indigo-500', 'ring-offset-2');
725
+ });
726
+ });
727
+
728
+ // Photo upload
729
+ uploadBtn.addEventListener('click', () => photoUpload.click());
730
+
731
+ photoUpload.addEventListener('change', (e) => {
732
+ if (e.target.files.length > 0) {
733
+ const file = e.target.files[0];
734
+ const reader = new FileReader();
735
+
736
+ reader.onload = (event) => {
737
+ uploadedImage.src = event.target.result;
738
+ uploadPreview.classList.remove('hidden');
739
+ };
740
+
741
+ reader.readAsDataURL(file);
742
+ }
743
+ });
744
+
745
+ // Remove uploaded photo
746
+ removeUpload.addEventListener('click', () => {
747
+ uploadedImage.src = '';
748
+ uploadPreview.classList.add('hidden');
749
+ photoUpload.value = '';
750
+ });
751
+
752
+ // Style upload
753
+ uploadStyleBtn.addEventListener('click', () => styleUpload.click());
754
+
755
+ styleUpload.addEventListener('change', (e) => {
756
+ if (e.target.files.length > 0) {
757
+ const file = e.target.files[0];
758
+ const reader = new FileReader();
759
+
760
+ reader.onload = (event) => {
761
+ uploadedStyleImage.src = event.target.result;
762
+ stylePreview.classList.remove('hidden');
763
+
764
+ // Update wig details
765
+ const wigDetails = document.getElementById('wigDetails');
766
+ wigDetails.textContent = `${file.name} (${(file.size/1024/1024).toFixed(1)}MB)`;
767
+ };
768
+
769
+ reader.readAsDataURL(file);
770
+ }
771
+ });
772
+
773
+ // Remove/change uploaded style
774
+ removeStyle.addEventListener('click', () => {
775
+ styleUpload.value = '';
776
+ styleUpload.click();
777
+ });
778
+
779
+ // Analyze wig button
780
+ document.getElementById('analyzeWigBtn').addEventListener('click', () => {
781
+ if (uploadedStyleImage.src) {
782
+ // Show processing animation
783
+ const analyzeBtn = document.getElementById('analyzeWigBtn');
784
+ analyzeBtn.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i> Analyzing...';
785
+ analyzeBtn.disabled = true;
786
+
787
+ // Simulate analysis (in real app, this would call backend)
788
+ setTimeout(() => {
789
+ analyzeBtn.innerHTML = '<i class="fas fa-check mr-2"></i> Analyzed';
790
+
791
+ // Update wig details with analysis results
792
+ const wigDetails = document.getElementById('wigDetails');
793
+ wigDetails.innerHTML = `
794
+ <span class="font-medium">Long Straight Wig</span><br>
795
+ <span class="text-indigo-600">✓ Shape detected</span><br>
796
+ <span class="text-indigo-600">✓ Color analyzed (#5a3e2a)</span>
797
+ `;
798
+
799
+ // Enable generate button
800
+ document.getElementById('generateBtn').disabled = false;
801
+ }, 2000);
802
+ } else {
803
+ alert('Please upload a wig image first');
804
+ }
805
+ });
806
+
807
+ // Generate button click
808
+ generateBtn.addEventListener('click', () => {
809
+ // Check if photo is uploaded
810
+ if (!uploadPreview.classList.contains('hidden') || !capturePreview.classList.contains('hidden')) {
811
+ // Show processing state
812
+ emptyState.classList.add('hidden');
813
+ resultContainer.classList.add('hidden');
814
+ processingContainer.classList.remove('hidden');
815
+
816
+ // Simulate processing steps
817
+ simulateProcessing();
818
+
819
+ // After processing, show result
820
+ setTimeout(() => {
821
+ processingContainer.classList.add('hidden');
822
+ resultContainer.classList.remove('hidden');
823
+
824
+ // Set the generated result from processing
825
+ resultImage.src = "/generated-results/result.jpg";
826
+ resultImage.alt = "Generated wig try-on result";
827
+ }, 3000);
828
+ } else {
829
+ alert('Please upload a photo or take one with your camera first.');
830
+ }
831
+ });
832
+
833
+ // VIP modal
834
+ closeVipModal.addEventListener('click', () => {
835
+ vipModal.classList.add('hidden');
836
+ });
837
+
838
+ useCreditsBtn.addEventListener('click', () => {
839
+ // In a real app, would deduct credits and proceed
840
+ alert('VIP style unlocked with 3 credits!');
841
+ vipModal.classList.add('hidden');
842
+
843
+ // Find and select the VIP item
844
+ galleryItems.forEach(item => {
845
+ if (item.getAttribute('data-vip') === 'true' && item.classList.contains('selected')) {
846
+ const styleName = item.querySelector('div').textContent.trim();
847
+ selectedStyleName.textContent = styleName;
848
+ }
849
+ });
850
+ });
851
+
852
+ buyCreditsBtn.addEventListener('click', () => {
853
+ vipModal.classList.add('hidden');
854
+ creditsModal.classList.remove('hidden');
855
+ });
856
+
857
+ // Credits modal
858
+ creditsBtn.addEventListener('click', () => {
859
+ creditsModal.classList.remove('hidden');
860
+ });
861
+
862
+ closeCreditsModal.addEventListener('click', () => {
863
+ creditsModal.classList.add('hidden');
864
+ });
865
+
866
+ // Camera functionality
867
+ function initCamera() {
868
+ if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
869
+ navigator.mediaDevices.getUserMedia({ video: true })
870
+ .then(stream => {
871
+ cameraVideo.srcObject = stream;
872
+ })
873
+ .catch(error => {
874
+ console.error("Camera access error:", error);
875
+ alert("Could not access the camera. Please check permissions.");
876
+ });
877
+ }
878
+ }
879
+
880
+ function stopCamera() {
881
+ if (cameraVideo.srcObject) {
882
+ cameraVideo.srcObject.getTracks().forEach(track => track.stop());
883
+ cameraVideo.srcObject = null;
884
+ }
885
+ }
886
+
887
+ // Capture photo from camera
888
+ captureBtn.addEventListener('click', () => {
889
+ const context = capturedImage.getContext('2d');
890
+ capturedImage.width = cameraVideo.videoWidth;
891
+ capturedImage.height = cameraVideo.videoHeight;
892
+ context.drawImage(cameraVideo, 0, 0, capturedImage.width, capturedImage.height);
893
+
894
+ capturePreview.classList.remove('hidden');
895
+ });
896
+
897
+ // Retake photo
898
+ retakeBtn.addEventListener('click', () => {
899
+ capturePreview.classList.add('hidden');
900
+ });
901
+
902
+ // Simulate processing steps
903
+ function simulateProcessing() {
904
+ let progress = 0;
905
+ const interval = setInterval(() => {
906
+ progress += 5;
907
+ progressFill.style.width = `${progress}%`;
908
+
909
+ // Update active step
910
+ if (progress >= 20) processingSteps[1].classList.add('active');
911
+ if (progress >= 40) {
912
+ processingSteps[1].classList.remove('active');
913
+ processingSteps[1].classList.add('completed');
914
+ processingSteps[2].classList.add('active');
915
+ }
916
+ if (progress >= 60) {
917
+ processingSteps[2].classList.remove('active');
918
+ processingSteps[2].classList.add('completed');
919
+ processingSteps[3].classList.add('active');
920
+ }
921
+ if (progress >= 80) {
922
+ processingSteps[3].classList.remove('active');
923
+ processingSteps[3].classList.add('completed');
924
+ processingSteps[4].classList.add('active');
925
+ }
926
+ if (progress >= 100) {
927
+ processingSteps[4].classList.remove('active');
928
+ processingSteps[4].classList.add('completed');
929
+ clearInterval(interval);
930
+ }
931
+ }, 100);
932
+ }
933
+
934
+ // Initialize with first tab active
935
+ document.querySelector('.tab-btn').click();
936
+ document.querySelector('.style-tab-btn').click();
937
+ document.querySelector('.category-btn').click();
938
+
939
+ // Clean up camera on page unload
940
+ window.addEventListener('beforeunload', () => {
941
+ stopCamera();
942
+ });
943
+ </script>
944
+ <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=savvysmith/wigapp" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
945
+ </html>