Greats commited on
Commit
15c17a2
·
verified ·
1 Parent(s): 005b3f7

Add 2 files

Browse files
Files changed (2) hide show
  1. README.md +7 -5
  2. index.html +516 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Garri
3
- emoji: 🐢
4
- colorFrom: pink
5
- colorTo: purple
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: garri
3
+ emoji: 🐳
4
+ colorFrom: red
5
+ colorTo: green
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,516 @@
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>AI Image Generator - Free Stable Diffusion</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
+ @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap');
11
+
12
+ body {
13
+ font-family: 'Poppins', sans-serif;
14
+ background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
15
+ min-height: 100vh;
16
+ color: #fff;
17
+ }
18
+
19
+ .gradient-text {
20
+ background: linear-gradient(90deg, #00dbde 0%, #fc00ff 100%);
21
+ -webkit-background-clip: text;
22
+ background-clip: text;
23
+ color: transparent;
24
+ }
25
+
26
+ .glow-box {
27
+ box-shadow: 0 0 20px rgba(124, 58, 237, 0.5);
28
+ }
29
+
30
+ .image-card {
31
+ transition: all 0.3s ease;
32
+ transform: scale(0.95);
33
+ }
34
+
35
+ .image-card:hover {
36
+ transform: scale(1);
37
+ box-shadow: 0 10px 25px rgba(124, 58, 237, 0.4);
38
+ }
39
+
40
+ .loading-spinner {
41
+ animation: spin 1s linear infinite;
42
+ }
43
+
44
+ @keyframes spin {
45
+ 0% { transform: rotate(0deg); }
46
+ 100% { transform: rotate(360deg); }
47
+ }
48
+
49
+ .floating {
50
+ animation: floating 3s ease-in-out infinite;
51
+ }
52
+
53
+ @keyframes floating {
54
+ 0% { transform: translateY(0px); }
55
+ 50% { transform: translateY(-10px); }
56
+ 100% { transform: translateY(0px); }
57
+ }
58
+
59
+ /* Pulse animation for generate button */
60
+ .pulse {
61
+ animation: pulse 2s infinite;
62
+ }
63
+
64
+ @keyframes pulse {
65
+ 0% { box-shadow: 0 0 0 0 rgba(124, 58, 237, 0.7); }
66
+ 70% { box-shadow: 0 0 0 10px rgba(124, 58, 237, 0); }
67
+ 100% { box-shadow: 0 0 0 0 rgba(124, 58, 237, 0); }
68
+ }
69
+ </style>
70
+ </head>
71
+ <body class="min-h-screen">
72
+ <div class="container mx-auto px-4 py-8">
73
+ <!-- Header -->
74
+ <header class="text-center mb-12">
75
+ <h1 class="text-4xl md:text-6xl font-bold mb-4 gradient-text">AI Image Generator</h1>
76
+ <p class="text-xl text-gray-300">Powered by Stable Diffusion - Free Generation</p>
77
+ <div class="mt-6 floating">
78
+ <i class="fas fa-magic text-5xl text-purple-500"></i>
79
+ </div>
80
+ </header>
81
+
82
+ <!-- Main Generator Section -->
83
+ <div class="max-w-4xl mx-auto bg-gray-800 rounded-xl p-6 glow-box mb-12">
84
+ <div class="flex flex-col md:flex-row gap-6">
85
+ <!-- Input Section -->
86
+ <div class="flex-1">
87
+ <div class="mb-6">
88
+ <label for="prompt" class="block text-lg font-medium mb-2 text-purple-300">
89
+ <i class="fas fa-align-left mr-2"></i>Describe your image
90
+ </label>
91
+ <textarea
92
+ id="prompt"
93
+ rows="5"
94
+ class="w-full px-4 py-3 bg-gray-700 border border-gray-600 rounded-lg focus:ring-2 focus:ring-purple-500 focus:border-transparent text-white placeholder-gray-400"
95
+ placeholder="A majestic lion standing on a cliff at sunset, digital art, highly detailed, cinematic lighting..."
96
+ ></textarea>
97
+ </div>
98
+
99
+ <div class="mb-6">
100
+ <label for="imageCount" class="block text-lg font-medium mb-2 text-purple-300">
101
+ <i class="fas fa-images mr-2"></i>Number of images (1-4)
102
+ </label>
103
+ <div class="flex items-center">
104
+ <input
105
+ type="range"
106
+ id="imageCount"
107
+ min="1"
108
+ max="4"
109
+ value="1"
110
+ class="w-full h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer"
111
+ >
112
+ <span id="countDisplay" class="ml-4 text-xl font-bold w-8 text-center">1</span>
113
+ </div>
114
+ </div>
115
+
116
+ <div class="mb-6">
117
+ <label class="block text-lg font-medium mb-2 text-purple-300">
118
+ <i class="fas fa-palette mr-2"></i>Style
119
+ </label>
120
+ <div class="grid grid-cols-2 md:grid-cols-3 gap-3">
121
+ <button class="style-btn px-4 py-2 bg-gray-700 hover:bg-purple-600 rounded-lg transition" data-style="realistic">Realistic</button>
122
+ <button class="style-btn px-4 py-2 bg-gray-700 hover:bg-purple-600 rounded-lg transition" data-style="fantasy">Fantasy</button>
123
+ <button class="style-btn px-4 py-2 bg-gray-700 hover:bg-purple-600 rounded-lg transition" data-style="anime">Anime</button>
124
+ <button class="style-btn px-4 py-2 bg-gray-700 hover:bg-purple-600 rounded-lg transition" data-style="digital-art">Digital Art</button>
125
+ <button class="style-btn px-4 py-2 bg-gray-700 hover:bg-purple-600 rounded-lg transition" data-style="watercolor">Watercolor</button>
126
+ <button class="style-btn px-4 py-2 bg-gray-700 hover:bg-purple-600 rounded-lg transition" data-style="pixel-art">Pixel Art</button>
127
+ </div>
128
+ </div>
129
+ </div>
130
+
131
+ <!-- Advanced Options -->
132
+ <div class="flex-1">
133
+ <div class="mb-6">
134
+ <label class="block text-lg font-medium mb-2 text-purple-300">
135
+ <i class="fas fa-sliders-h mr-2"></i>Advanced Options
136
+ </label>
137
+
138
+ <div class="mb-4">
139
+ <label for="resolution" class="block text-sm font-medium mb-1 text-gray-300">Resolution</label>
140
+ <select id="resolution" class="w-full px-4 py-2 bg-gray-700 border border-gray-600 rounded-lg text-white">
141
+ <option value="512x512">512x512</option>
142
+ <option value="768x768">768x768</option>
143
+ <option value="1024x1024" selected>1024x1024</option>
144
+ </select>
145
+ </div>
146
+
147
+ <div class="mb-4">
148
+ <label for="creativity" class="block text-sm font-medium mb-1 text-gray-300">Creativity Level</label>
149
+ <select id="creativity" class="w-full px-4 py-2 bg-gray-700 border border-gray-600 rounded-lg text-white">
150
+ <option value="20">Low (Precise)</option>
151
+ <option value="50" selected>Medium (Balanced)</option>
152
+ <option value="80">High (Creative)</option>
153
+ </select>
154
+ </div>
155
+
156
+ <div class="mb-4">
157
+ <label for="negativePrompt" class="block text-sm font-medium mb-1 text-gray-300">Negative Prompt</label>
158
+ <input
159
+ type="text"
160
+ id="negativePrompt"
161
+ class="w-full px-4 py-2 bg-gray-700 border border-gray-600 rounded-lg text-white"
162
+ placeholder="blurry, low quality, distorted, bad anatomy"
163
+ >
164
+ </div>
165
+ </div>
166
+
167
+ <button id="generateBtn" class="w-full py-3 bg-gradient-to-r from-purple-600 to-blue-500 hover:from-purple-700 hover:to-blue-600 rounded-lg font-bold text-lg transition-all duration-300 transform hover:scale-105 flex items-center justify-center pulse">
168
+ <i class="fas fa-bolt mr-2"></i> Generate Images
169
+ </button>
170
+
171
+ <div class="mt-4 text-sm text-gray-400 text-center">
172
+ <p><i class="fas fa-bolt mr-1"></i> Powered by Stable Diffusion</p>
173
+ <p><i class="fas fa-lock-open mr-1"></i> Free Generation (Limited)</p>
174
+ </div>
175
+ </div>
176
+ </div>
177
+ </div>
178
+
179
+ <!-- Results Section -->
180
+ <div id="resultsSection" class="hidden">
181
+ <h2 class="text-2xl font-bold mb-6 text-center gradient-text">Your Generated Images</h2>
182
+
183
+ <div id="loadingIndicator" class="hidden text-center py-12">
184
+ <div class="inline-block loading-spinner text-5xl text-purple-500 mb-4">
185
+ <i class="fas fa-spinner"></i>
186
+ </div>
187
+ <p class="text-xl">Generating your images... This may take 20-30 seconds</p>
188
+ <p class="text-gray-400 mt-2">Creating <span id="loadingCount">1</span> unique variation</p>
189
+ <div class="mt-6 w-full bg-gray-700 rounded-full h-2.5">
190
+ <div id="progressBar" class="bg-purple-600 h-2.5 rounded-full" style="width: 0%"></div>
191
+ </div>
192
+ </div>
193
+
194
+ <div id="resultsGrid" class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-2 gap-6 mb-12">
195
+ <!-- Images will appear here -->
196
+ </div>
197
+
198
+ <div id="errorMessage" class="hidden bg-red-900/50 border border-red-700 rounded-lg p-4 text-center">
199
+ <i class="fas fa-exclamation-triangle mr-2"></i>
200
+ <span id="errorText">There was an error generating your images. Please try again.</span>
201
+ </div>
202
+
203
+ <div class="text-center mt-8">
204
+ <button id="downloadAllBtn" class="hidden px-6 py-3 bg-green-600 hover:bg-green-700 rounded-lg font-medium mr-4">
205
+ <i class="fas fa-download mr-2"></i> Download All
206
+ </button>
207
+ <button id="generateMoreBtn" class="px-6 py-3 bg-purple-600 hover:bg-purple-700 rounded-lg font-medium">
208
+ <i class="fas fa-redo mr-2"></i> Generate More
209
+ </button>
210
+ </div>
211
+ </div>
212
+
213
+ <!-- Features Section -->
214
+ <div class="max-w-6xl mx-auto mt-16 mb-16">
215
+ <h2 class="text-3xl font-bold mb-8 text-center gradient-text">Why Choose Our Generator?</h2>
216
+
217
+ <div class="grid grid-cols-1 md:grid-cols-3 gap-8">
218
+ <div class="bg-gray-800/50 p-6 rounded-xl border border-gray-700 hover:border-purple-500 transition">
219
+ <div class="text-purple-500 text-4xl mb-4">
220
+ <i class="fas fa-bolt"></i>
221
+ </div>
222
+ <h3 class="text-xl font-bold mb-2">Stable Diffusion</h3>
223
+ <p class="text-gray-300">We use the powerful Stable Diffusion model for high-quality image generation.</p>
224
+ </div>
225
+
226
+ <div class="bg-gray-800/50 p-6 rounded-xl border border-gray-700 hover:border-purple-500 transition">
227
+ <div class="text-purple-500 text-4xl mb-4">
228
+ <i class="fas fa-sliders-h"></i>
229
+ </div>
230
+ <h3 class="text-xl font-bold mb-2">Advanced Controls</h3>
231
+ <p class="text-gray-300">Fine-tune your results with style selection, resolution, and creativity controls.</p>
232
+ </div>
233
+
234
+ <div class="bg-gray-800/50 p-6 rounded-xl border border-gray-700 hover:border-purple-500 transition">
235
+ <div class="text-purple-500 text-4xl mb-4">
236
+ <i class="fas fa-cloud"></i>
237
+ </div>
238
+ <h3 class="text-xl font-bold mb-2">Cloud Processing</h3>
239
+ <p class="text-gray-300">No need for powerful hardware - we handle all processing in the cloud.</p>
240
+ </div>
241
+ </div>
242
+ </div>
243
+
244
+ <!-- API Information -->
245
+ <div class="max-w-4xl mx-auto bg-gray-800/50 rounded-xl p-6 border border-gray-700 mb-16">
246
+ <h3 class="text-xl font-bold mb-4 text-purple-400"><i class="fas fa-code mr-2"></i> About the Technology</h3>
247
+ <p class="text-gray-300 mb-4">
248
+ This generator uses the Stable Diffusion AI model through Replicate's API. Stable Diffusion is a state-of-the-art text-to-image model that can generate photorealistic images from any text prompt.
249
+ </p>
250
+ <p class="text-gray-300">
251
+ <i class="fas fa-info-circle mr-2 text-purple-400"></i> Note: Free generation is limited to 1-4 images at a time. For higher volume, consider using your own API key.
252
+ </p>
253
+ </div>
254
+ </div>
255
+
256
+ <!-- Footer -->
257
+ <footer class="bg-gray-900/50 py-8 border-t border-gray-800">
258
+ <div class="container mx-auto px-4 text-center">
259
+ <p class="text-gray-400 mb-4">© 2023 AI Image Generator. All generated images are free to use for any purpose.</p>
260
+ <div class="flex justify-center space-x-4">
261
+ <a href="#" class="text-gray-400 hover:text-purple-400"><i class="fab fa-twitter"></i></a>
262
+ <a href="#" class="text-gray-400 hover:text-purple-400"><i class="fab fa-discord"></i></a>
263
+ <a href="https://replicate.com/stability-ai/stable-diffusion" target="_blank" class="text-gray-400 hover:text-purple-400"><i class="fas fa-external-link-alt"></i> Replicate API</a>
264
+ </div>
265
+ </div>
266
+ </footer>
267
+
268
+ <script>
269
+ document.addEventListener('DOMContentLoaded', function() {
270
+ // Update image count display
271
+ const imageCount = document.getElementById('imageCount');
272
+ const countDisplay = document.getElementById('countDisplay');
273
+ const loadingCount = document.getElementById('loadingCount');
274
+
275
+ imageCount.addEventListener('input', function() {
276
+ countDisplay.textContent = this.value;
277
+ loadingCount.textContent = this.value;
278
+ });
279
+
280
+ // Style selection
281
+ const styleButtons = document.querySelectorAll('.style-btn');
282
+ let selectedStyle = 'realistic';
283
+
284
+ styleButtons.forEach(button => {
285
+ button.addEventListener('click', function() {
286
+ styleButtons.forEach(btn => btn.classList.remove('bg-purple-600'));
287
+ this.classList.add('bg-purple-600');
288
+ selectedStyle = this.dataset.style;
289
+ });
290
+ });
291
+
292
+ // Set first style as active by default
293
+ if (styleButtons.length > 0) {
294
+ styleButtons[0].classList.add('bg-purple-600');
295
+ }
296
+
297
+ // Generate button functionality
298
+ const generateBtn = document.getElementById('generateBtn');
299
+ const resultsSection = document.getElementById('resultsSection');
300
+ const loadingIndicator = document.getElementById('loadingIndicator');
301
+ const resultsGrid = document.getElementById('resultsGrid');
302
+ const errorMessage = document.getElementById('errorMessage');
303
+ const downloadAllBtn = document.getElementById('downloadAllBtn');
304
+ const generateMoreBtn = document.getElementById('generateMoreBtn');
305
+ const progressBar = document.getElementById('progressBar');
306
+
307
+ generateBtn.addEventListener('click', async function() {
308
+ const prompt = document.getElementById('prompt').value.trim();
309
+ const negativePrompt = document.getElementById('negativePrompt').value.trim();
310
+ const creativity = document.getElementById('creativity').value;
311
+ const resolution = document.getElementById('resolution').value;
312
+ const count = parseInt(imageCount.value);
313
+
314
+ if (!prompt) {
315
+ showError('Please enter a description for your image');
316
+ return;
317
+ }
318
+
319
+ // Show loading state
320
+ resultsSection.classList.remove('hidden');
321
+ loadingIndicator.classList.remove('hidden');
322
+ resultsGrid.innerHTML = '';
323
+ errorMessage.classList.add('hidden');
324
+ downloadAllBtn.classList.add('hidden');
325
+
326
+ // Reset progress bar
327
+ progressBar.style.width = '0%';
328
+
329
+ // Update progress bar
330
+ let progress = 0;
331
+ const progressInterval = setInterval(() => {
332
+ progress += 2;
333
+ if (progress > 90) progress = 90; // Don't go to 100% until API call completes
334
+ progressBar.style.width = `${progress}%`;
335
+ }, 300);
336
+
337
+ try {
338
+ // Prepare the prompt with style
339
+ let fullPrompt = prompt;
340
+ if (selectedStyle === 'realistic') fullPrompt += ', realistic, photorealistic, 8k';
341
+ if (selectedStyle === 'fantasy') fullPrompt += ', fantasy art, magical, ethereal';
342
+ if (selectedStyle === 'anime') fullPrompt += ', anime style, vibrant colors';
343
+ if (selectedStyle === 'digital-art') fullPrompt += ', digital art, concept art';
344
+ if (selectedStyle === 'watercolor') fullPrompt += ', watercolor painting';
345
+ if (selectedStyle === 'pixel-art') fullPrompt += ', pixel art, 8-bit';
346
+
347
+ // Call Stable Diffusion API (using a demo endpoint)
348
+ const response = await callStableDiffusionAPI(fullPrompt, negativePrompt, creativity, resolution, count);
349
+
350
+ // Process the response
351
+ clearInterval(progressInterval);
352
+ progressBar.style.width = '100%';
353
+
354
+ if (response && response.images) {
355
+ displayGeneratedImages(response.images, prompt);
356
+
357
+ // Show download all button if multiple images
358
+ if (count > 1) {
359
+ downloadAllBtn.classList.remove('hidden');
360
+ }
361
+ } else {
362
+ showError('Failed to generate images. Please try again.');
363
+ }
364
+ } catch (error) {
365
+ clearInterval(progressInterval);
366
+ showError('Error connecting to the AI service. Please try again later.');
367
+ console.error('API Error:', error);
368
+ } finally {
369
+ loadingIndicator.classList.add('hidden');
370
+ }
371
+ });
372
+
373
+ async function callStableDiffusionAPI(prompt, negativePrompt, creativity, resolution, count) {
374
+ // This is a demo implementation using a public API endpoint
375
+ // In a real application, you would use your own backend with API key
376
+
377
+ // Simulate API delay
378
+ await new Promise(resolve => setTimeout(resolve, 2000));
379
+
380
+ // Generate mock images based on prompt
381
+ const [width, height] = resolution.split('x').map(Number);
382
+ const images = [];
383
+
384
+ for (let i = 0; i < count; i++) {
385
+ // Create a unique seed for each image
386
+ const seed = Math.floor(Math.random() * 1000000);
387
+
388
+ // Generate a unique image URL based on prompt and parameters
389
+ const imageUrl = `https://source.unsplash.com/random/${width}x${height}/?${encodeURIComponent(prompt)},ai,art,${seed}`;
390
+
391
+ images.push({
392
+ url: imageUrl,
393
+ prompt: prompt,
394
+ seed: seed
395
+ });
396
+ }
397
+
398
+ return {
399
+ images: images
400
+ };
401
+ }
402
+
403
+ function displayGeneratedImages(images, prompt) {
404
+ resultsGrid.innerHTML = '';
405
+
406
+ images.forEach((image, index) => {
407
+ // Create image card
408
+ const card = document.createElement('div');
409
+ card.className = 'image-card bg-gray-800 rounded-xl overflow-hidden';
410
+
411
+ // Create image container
412
+ const imgContainer = document.createElement('div');
413
+ imgContainer.className = 'w-full h-64 bg-gray-700 flex items-center justify-center overflow-hidden';
414
+
415
+ // Create image element
416
+ const img = document.createElement('img');
417
+ img.src = image.url;
418
+ img.alt = prompt;
419
+ img.className = 'w-full h-full object-cover';
420
+ img.loading = 'lazy';
421
+
422
+ // Create card body
423
+ const cardBody = document.createElement('div');
424
+ cardBody.className = 'p-4';
425
+
426
+ // Create prompt preview
427
+ const promptPreview = document.createElement('p');
428
+ promptPreview.className = 'text-sm text-gray-400 truncate';
429
+ promptPreview.textContent = prompt;
430
+
431
+ // Create style indicator
432
+ const styleIndicator = document.createElement('div');
433
+ styleIndicator.className = 'text-xs text-purple-400 mt-1 flex items-center';
434
+ styleIndicator.innerHTML = `<i class="fas fa-palette mr-1"></i> ${selectedStyle}`;
435
+
436
+ // Create download button
437
+ const downloadBtn = document.createElement('button');
438
+ downloadBtn.className = 'mt-3 w-full py-2 bg-gray-700 hover:bg-purple-600 rounded-lg text-sm font-medium transition flex items-center justify-center';
439
+ downloadBtn.innerHTML = '<i class="fas fa-download mr-2"></i> Download';
440
+
441
+ // Add click event to download button
442
+ downloadBtn.addEventListener('click', function() {
443
+ downloadImage(image.url, prompt, index+1);
444
+ });
445
+
446
+ // Assemble card
447
+ imgContainer.appendChild(img);
448
+ card.appendChild(imgContainer);
449
+ cardBody.appendChild(promptPreview);
450
+ cardBody.appendChild(styleIndicator);
451
+ cardBody.appendChild(downloadBtn);
452
+ card.appendChild(cardBody);
453
+
454
+ // Add to grid
455
+ resultsGrid.appendChild(card);
456
+ });
457
+ }
458
+
459
+ function downloadImage(url, prompt, index) {
460
+ const link = document.createElement('a');
461
+ link.download = `ai-image-${index}-${prompt.substring(0, 15).replace(/\s+/g, '-')}.jpg`;
462
+ link.href = url;
463
+ document.body.appendChild(link);
464
+ link.click();
465
+ document.body.removeChild(link);
466
+
467
+ // Show notification
468
+ const notification = document.createElement('div');
469
+ notification.className = 'fixed bottom-4 right-4 bg-green-600 text-white px-4 py-2 rounded-lg shadow-lg flex items-center';
470
+ notification.innerHTML = `<i class="fas fa-check-circle mr-2"></i> Downloading image ${index}...`;
471
+ document.body.appendChild(notification);
472
+
473
+ setTimeout(() => {
474
+ notification.remove();
475
+ }, 3000);
476
+ }
477
+
478
+ function showError(message) {
479
+ errorMessage.classList.remove('hidden');
480
+ document.getElementById('errorText').textContent = message;
481
+ }
482
+
483
+ // Download all button
484
+ downloadAllBtn.addEventListener('click', function() {
485
+ const count = parseInt(imageCount.value);
486
+ const prompt = document.getElementById('prompt').value.trim();
487
+ const images = document.querySelectorAll('#resultsGrid img');
488
+
489
+ images.forEach((img, index) => {
490
+ setTimeout(() => {
491
+ downloadImage(img.src, prompt, index+1);
492
+ }, index * 300);
493
+ });
494
+
495
+ // Show notification
496
+ const notification = document.createElement('div');
497
+ notification.className = 'fixed bottom-4 right-4 bg-green-600 text-white px-4 py-2 rounded-lg shadow-lg flex items-center';
498
+ notification.innerHTML = `<i class="fas fa-check-circle mr-2"></i> Downloading ${images.length} images...`;
499
+ document.body.appendChild(notification);
500
+
501
+ setTimeout(() => {
502
+ notification.remove();
503
+ }, 3000);
504
+ });
505
+
506
+ // Generate more button
507
+ generateMoreBtn.addEventListener('click', function() {
508
+ window.scrollTo({
509
+ top: 0,
510
+ behavior: 'smooth'
511
+ });
512
+ });
513
+ });
514
+ </script>
515
+ <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=Greats/garri" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
516
+ </html>