Keeg42069 commited on
Commit
5a4e91b
·
verified ·
1 Parent(s): 9a69261

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. index.html +547 -19
index.html CHANGED
@@ -1,19 +1,547 @@
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>RGB Spectrum Generator | 100 Unique Colors</title>
7
+ <style>
8
+ :root {
9
+ --bg-color: #0f172a;
10
+ --card-bg: #1e293b;
11
+ --text-primary: #f8fafc;
12
+ --text-secondary: #94a3b8;
13
+ --accent: #3b82f6;
14
+ --accent-hover: #2563eb;
15
+ --border: #334155;
16
+ --success: #22c55e;
17
+ --font-family: 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
18
+ }
19
+
20
+ * {
21
+ box-sizing: border-box;
22
+ margin: 0;
23
+ padding: 0;
24
+ }
25
+
26
+ body {
27
+ font-family: var(--font-family);
28
+ background-color: var(--bg-color);
29
+ color: var(--text-primary);
30
+ line-height: 1.6;
31
+ min-height: 100vh;
32
+ display: flex;
33
+ flex-direction: column;
34
+ }
35
+
36
+ /* Header Styling */
37
+ header {
38
+ background-color: rgba(30, 41, 59, 0.8);
39
+ backdrop-filter: blur(10px);
40
+ border-bottom: 1px solid var(--border);
41
+ padding: 1rem 2rem;
42
+ position: sticky;
43
+ top: 0;
44
+ z-index: 100;
45
+ display: flex;
46
+ justify-content: space-between;
47
+ align-items: center;
48
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
49
+ }
50
+
51
+ .brand {
52
+ display: flex;
53
+ flex-direction: column;
54
+ }
55
+
56
+ h1 {
57
+ font-size: 1.5rem;
58
+ font-weight: 700;
59
+ letter-spacing: -0.025em;
60
+ }
61
+
62
+ .subtitle {
63
+ font-size: 0.875rem;
64
+ color: var(--text-secondary);
65
+ }
66
+
67
+ .anycoder-link {
68
+ font-size: 0.85rem;
69
+ color: var(--accent);
70
+ text-decoration: none;
71
+ font-weight: 600;
72
+ transition: color 0.2s;
73
+ border: 1px solid var(--accent);
74
+ padding: 0.4rem 0.8rem;
75
+ border-radius: 6px;
76
+ }
77
+
78
+ .anycoder-link:hover {
79
+ color: var(--text-primary);
80
+ background-color: var(--accent);
81
+ }
82
+
83
+ /* Main Content */
84
+ main {
85
+ flex: 1;
86
+ padding: 2rem;
87
+ max-width: 1400px;
88
+ margin: 0 auto;
89
+ width: 100%;
90
+ }
91
+
92
+ .controls {
93
+ display: flex;
94
+ justify-content: space-between;
95
+ align-items: center;
96
+ margin-bottom: 2rem;
97
+ flex-wrap: wrap;
98
+ gap: 1rem;
99
+ }
100
+
101
+ .stats {
102
+ color: var(--text-secondary);
103
+ font-size: 0.9rem;
104
+ }
105
+
106
+ .btn {
107
+ background-color: var(--accent);
108
+ color: white;
109
+ border: none;
110
+ padding: 0.75rem 1.5rem;
111
+ border-radius: 8px;
112
+ font-weight: 600;
113
+ cursor: pointer;
114
+ transition: all 0.2s ease;
115
+ display: inline-flex;
116
+ align-items: center;
117
+ gap: 0.5rem;
118
+ font-size: 1rem;
119
+ }
120
+
121
+ .btn:hover {
122
+ background-color: var(--accent-hover);
123
+ transform: translateY(-1px);
124
+ box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3);
125
+ }
126
+
127
+ .btn:active {
128
+ transform: translateY(0);
129
+ }
130
+
131
+ .btn-secondary {
132
+ background-color: transparent;
133
+ border: 1px solid var(--border);
134
+ color: var(--text-secondary);
135
+ }
136
+
137
+ .btn-secondary:hover {
138
+ border-color: var(--text-primary);
139
+ color: var(--text-primary);
140
+ background-color: transparent;
141
+ box-shadow: none;
142
+ }
143
+
144
+ /* Grid System */
145
+ .gallery-grid {
146
+ display: grid;
147
+ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
148
+ gap: 1.5rem;
149
+ }
150
+
151
+ /* Color Card Styling */
152
+ .color-card {
153
+ background-color: var(--card-bg);
154
+ border: 1px solid var(--border);
155
+ border-radius: 12px;
156
+ overflow: hidden;
157
+ transition: transform 0.2s, box-shadow 0.2s;
158
+ display: flex;
159
+ flex-direction: column;
160
+ position: relative;
161
+ }
162
+
163
+ .color-card:hover {
164
+ transform: translateY(-4px);
165
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.3);
166
+ border-color: var(--accent);
167
+ }
168
+
169
+ .preview-container {
170
+ width: 100%;
171
+ aspect-ratio: 1;
172
+ background-color: #000;
173
+ position: relative;
174
+ overflow: hidden;
175
+ }
176
+
177
+ .preview-img {
178
+ width: 100%;
179
+ height: 100%;
180
+ object-fit: cover;
181
+ image-rendering: pixelated; /* Keeps the 256x256 crisp */
182
+ }
183
+
184
+ .card-info {
185
+ padding: 1rem;
186
+ display: flex;
187
+ flex-direction: column;
188
+ gap: 0.5rem;
189
+ }
190
+
191
+ .rgb-label {
192
+ font-family: 'Courier New', monospace;
193
+ font-size: 0.85rem;
194
+ color: var(--text-primary);
195
+ font-weight: 600;
196
+ word-break: break-all;
197
+ }
198
+
199
+ .hex-label {
200
+ font-size: 0.75rem;
201
+ color: var(--text-secondary);
202
+ }
203
+
204
+ .download-btn {
205
+ margin-top: auto;
206
+ background-color: var(--card-bg);
207
+ border: 1px solid var(--border);
208
+ color: var(--text-secondary);
209
+ padding: 0.5rem;
210
+ border-radius: 6px;
211
+ cursor: pointer;
212
+ font-size: 0.8rem;
213
+ transition: all 0.2s;
214
+ display: flex;
215
+ justify-content: center;
216
+ align-items: center;
217
+ gap: 0.4rem;
218
+ }
219
+
220
+ .download-btn:hover {
221
+ border-color: var(--accent);
222
+ color: var(--accent);
223
+ background-color: rgba(59, 130, 246, 0.1);
224
+ }
225
+
226
+ /* Footer */
227
+ footer {
228
+ text-align: center;
229
+ padding: 2rem;
230
+ color: var(--text-secondary);
231
+ border-top: 1px solid var(--border);
232
+ margin-top: 2rem;
233
+ font-size: 0.875rem;
234
+ }
235
+
236
+ /* Toast Notification */
237
+ .toast {
238
+ position: fixed;
239
+ bottom: 2rem;
240
+ right: 2rem;
241
+ background-color: var(--success);
242
+ color: white;
243
+ padding: 1rem 1.5rem;
244
+ border-radius: 8px;
245
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.2);
246
+ transform: translateY(150%);
247
+ transition: transform 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
248
+ z-index: 1000;
249
+ font-weight: 600;
250
+ }
251
+
252
+ .toast.show {
253
+ transform: translateY(0);
254
+ }
255
+
256
+ /* Loading State */
257
+ .loading-overlay {
258
+ position: absolute;
259
+ top: 0;
260
+ left: 0;
261
+ width: 100%;
262
+ height: 100%;
263
+ background: rgba(15, 23, 42, 0.7);
264
+ display: flex;
265
+ align-items: center;
266
+ justify-content: center;
267
+ backdrop-filter: blur(2px);
268
+ z-index: 10;
269
+ opacity: 0;
270
+ pointer-events: none;
271
+ transition: opacity 0.3s;
272
+ }
273
+
274
+ .loading-overlay.active {
275
+ opacity: 1;
276
+ pointer-events: all;
277
+ }
278
+
279
+ .spinner {
280
+ width: 40px;
281
+ height: 40px;
282
+ border: 4px solid var(--border);
283
+ border-top-color: var(--accent);
284
+ border-radius: 50%;
285
+ animation: spin 1s linear infinite;
286
+ }
287
+
288
+ @keyframes spin {
289
+ to { transform: rotate(360deg); }
290
+ }
291
+
292
+ /* Responsive adjustments */
293
+ @media (max-width: 600px) {
294
+ header {
295
+ flex-direction: column;
296
+ gap: 1rem;
297
+ text-align: center;
298
+ }
299
+
300
+ .controls {
301
+ flex-direction: column;
302
+ align-items: stretch;
303
+ }
304
+
305
+ .btn {
306
+ justify-content: center;
307
+ }
308
+ }
309
+ </style>
310
+ </head>
311
+ <body>
312
+
313
+ <header>
314
+ <div class="brand">
315
+ <h1>RGB Spectrum Generator</h1>
316
+ <span class="subtitle">100 Unique 256x256 Images</span>
317
+ </div>
318
+ <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="anycoder-link">
319
+ Built with anycoder
320
+ </a>
321
+ </header>
322
+
323
+ <main>
324
+ <section class="controls">
325
+ <div class="stats" id="status-text">Ready to generate spectrum.</div>
326
+ <div style="display: flex; gap: 10px;">
327
+ <button class="btn btn-secondary" onclick="clearGallery()">Clear</button>
328
+ <button class="btn" onclick="generateSpectrum()">
329
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"></path><line x1="9" y1="9" x2="9" y2="9"></line><line x1="15" y1="9" x2="15" y2="9"></line><line x1="9" y1="15" x2="9" y2="15"></line><line x1="15" y1="15" x2="15" y2="15"></line></svg>
330
+ Generate Images
331
+ </button>
332
+ <button class="btn" id="download-all-btn" onclick="downloadAll()" style="display: none;">
333
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg>
334
+ Download All
335
+ </button>
336
+ </div>
337
+ </section>
338
+
339
+ <section class="gallery-grid" id="gallery">
340
+ <!-- Items will be injected here via JavaScript -->
341
+ </section>
342
+
343
+ <div class="loading-overlay" id="loader">
344
+ <div class="spinner"></div>
345
+ </div>
346
+ </main>
347
+
348
+ <footer>
349
+ <p>Generated entirely in-browser using HTML5 Canvas.</p>
350
+ </footer>
351
+
352
+ <div class="toast" id="toast">Images Generated Successfully!</div>
353
+
354
+ <script>
355
+ // Configuration
356
+ const TOTAL_IMAGES = 100;
357
+ const IMAGE_SIZE = 256;
358
+ const gallery = document.getElementById('gallery');
359
+ const statusText = document.getElementById('status-text');
360
+ const downloadAllBtn = document.getElementById('download-all-btn');
361
+ const loader = document.getElementById('loader');
362
+ const toast = document.getElementById('toast');
363
+
364
+ // State to store generated blob URLs for downloading later
365
+ let generatedItems = [];
366
+
367
+ /**
368
+ * Helper: Convert HSL to RGB
369
+ * h, s, l are in [0, 1]
370
+ * returns [r, g, b] in [0, 255]
371
+ */
372
+ function hslToRgb(h, s, l) {
373
+ let r, g, b;
374
+
375
+ if (s === 0) {
376
+ r = g = b = l; // achromatic
377
+ } else {
378
+ const hue2rgb = (p, q, t) => {
379
+ if (t < 0) t += 1;
380
+ if (t > 1) t -= 1;
381
+ if (t < 1 / 6) return p + (q - p) * 6 * t;
382
+ if (t < 1 / 2) return q;
383
+ if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
384
+ return p;
385
+ };
386
+
387
+ const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
388
+ const p = 2 * l - q;
389
+ r = hue2rgb(p, q, h + 1 / 3);
390
+ g = hue2rgb(p, q, h);
391
+ b = hue2rgb(p, q, h - 1 / 3);
392
+ }
393
+
394
+ return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
395
+ }
396
+
397
+ /**
398
+ * Helper: Convert RGB to Hex (for display purposes)
399
+ */
400
+ function rgbToHex(r, g, b) {
401
+ return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1).toUpperCase();
402
+ }
403
+
404
+ /**
405
+ * Generates a 256x256 canvas for a specific color and returns the Data URL
406
+ */
407
+ function createColorImage(r, g, b) {
408
+ const canvas = document.createElement('canvas');
409
+ canvas.width = IMAGE_SIZE;
410
+ canvas.height = IMAGE_SIZE;
411
+ const ctx = canvas.getContext('2d');
412
+
413
+ // Fill background
414
+ ctx.fillStyle = `rgb(${r}, ${g}, ${b})`;
415
+ ctx.fillRect(0, 0, IMAGE_SIZE, IMAGE_SIZE);
416
+
417
+ // Optional: Add a subtle text overlay in the corner indicating it's 256x256
418
+ // (Commented out to keep image pure color as requested, but useful for verification)
419
+ /*
420
+ ctx.fillStyle = 'rgba(0,0,0,0.1)';
421
+ ctx.font = '20px Arial';
422
+ ctx.fillText('256x256', 10, 30);
423
+ */
424
+
425
+ return canvas.toDataURL('image/png');
426
+ }
427
+
428
+ /**
429
+ * Main function to generate the spectrum
430
+ */
431
+ function generateSpectrum() {
432
+ // UI Updates
433
+ loader.classList.add('active');
434
+ statusText.textContent = "Generating 100 images...";
435
+ downloadAllBtn.style.display = 'none';
436
+ generatedItems = []; // Reset state
437
+
438
+ // Use setTimeout to allow UI to update (show loader) before heavy processing
439
+ setTimeout(() => {
440
+ const fragment = document.createDocumentFragment();
441
+
442
+ for (let i = 0; i < TOTAL_IMAGES; i++) {
443
+ // Calculate Hue (0 to 360 degrees)
444
+ // We step through the spectrum evenly
445
+ const hue = i / TOTAL_IMAGES;
446
+ const saturation = 1; // 100% saturation for vivid colors
447
+ const lightness = 0.5; // 50% lightness
448
+
449
+ const [r, g, b] = hslToRgb(hue, saturation, lightness);
450
+ const rgbString = `rgb(${r},${g},${b})`;
451
+ const hexString = rgbToHex(r, g, b);
452
+ const dataUrl = createColorImage(r, g, b);
453
+
454
+ // Store for bulk download
455
+ generatedItems.push({
456
+ name: `${rgbString}.png`,
457
+ url: dataUrl
458
+ });
459
+
460
+ // Create Card Elements
461
+ const card = document.createElement('div');
462
+ card.className = 'color-card';
463
+
464
+ card.innerHTML = `
465
+ <div class="preview-container">
466
+ <img src="${dataUrl}" class="preview-img" alt="Color patch ${rgbString}">
467
+ </div>
468
+ <div class="card-info">
469
+ <div class="rgb-label" title="${rgbString}">${rgbString}</div>
470
+ <div class="hex-label">${hexString}</div>
471
+ <button class="download-btn" onclick="triggerDownload('${rgbString}.png', '${dataUrl}')">
472
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg>
473
+ Download
474
+ </button>
475
+ </div>
476
+ `;
477
+
478
+ fragment.appendChild(card);
479
+ }
480
+
481
+ gallery.innerHTML = '';
482
+ gallery.appendChild(fragment);
483
+
484
+ // Final UI Updates
485
+ loader.classList.remove('active');
486
+ statusText.textContent = `Successfully generated ${TOTAL_IMAGES} images.`;
487
+ downloadAllBtn.style.display = 'inline-flex';
488
+ showToast();
489
+
490
+ }, 100); // Small delay to let the loader render
491
+ }
492
+
493
+ /**
494
+ * Triggers a single file download
495
+ */
496
+ function triggerDownload(filename, url) {
497
+ const link = document.createElement('a');
498
+ link.href = url;
499
+ link.download = filename;
500
+ document.body.appendChild(link);
501
+ link.click();
502
+ document.body.removeChild(link);
503
+ }
504
+
505
+ /**
506
+ * Triggers download for all generated images
507
+ * Note: Browsers may block multiple automatic downloads.
508
+ */
509
+ async function downloadAll() {
510
+ if (generatedItems.length === 0) return;
511
+
512
+ statusText.textContent = "Bulk download initiated...";
513
+
514
+ // Iterate with a small delay to prevent browser choking
515
+ for (let i = 0; i < generatedItems.length; i++) {
516
+ const item = generatedItems[i];
517
+ triggerDownload(item.name, item.url);
518
+
519
+ // Wait 200ms between downloads
520
+ await new Promise(r => setTimeout(r, 200));
521
+ }
522
+
523
+ statusText.textContent = "Bulk download finished.";
524
+ }
525
+
526
+ function clearGallery() {
527
+ gallery.innerHTML = '';
528
+ generatedItems = [];
529
+ downloadAllBtn.style.display = 'none';
530
+ statusText.textContent = "Gallery cleared.";
531
+ }
532
+
533
+ function showToast() {
534
+ toast.classList.add('show');
535
+ setTimeout(() => {
536
+ toast.classList.remove('show');
537
+ }, 3000);
538
+ }
539
+
540
+ // Generate automatically on load for better UX
541
+ window.addEventListener('DOMContentLoaded', () => {
542
+ generateSpectrum();
543
+ });
544
+
545
+ </script>
546
+ </body>
547
+ </html>