ParthSadaria commited on
Commit
dd553d1
·
verified ·
1 Parent(s): 666cb5e

Update image-playground.html

Browse files
Files changed (1) hide show
  1. image-playground.html +171 -71
image-playground.html CHANGED
@@ -1,5 +1,5 @@
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">
@@ -11,27 +11,6 @@
11
  font-family: 'DM Sans', sans-serif;
12
  }
13
 
14
- body {
15
- background-color: #fcfcfc;
16
- min-height: 100vh;
17
- }
18
-
19
- .card {
20
- border: 1px solid rgba(0, 0, 0, 0.1);
21
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
22
- border-radius: 12px;
23
- }
24
-
25
- .pulse {
26
- animation: pulse 2.5s infinite;
27
- }
28
-
29
- @keyframes pulse {
30
- 0% { opacity: 0.8; }
31
- 50% { opacity: 1; }
32
- 100% { opacity: 0.8; }
33
- }
34
-
35
  .loading {
36
  width: 40px;
37
  height: 40px;
@@ -41,6 +20,11 @@
41
  animation: rotation 1.2s linear infinite;
42
  }
43
 
 
 
 
 
 
44
  @keyframes rotation {
45
  0% { transform: rotate(0deg); }
46
  100% { transform: rotate(360deg); }
@@ -50,22 +34,84 @@
50
  border-radius: 8px;
51
  overflow: hidden;
52
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  </style>
54
  </head>
55
- <body class="p-4 md:p-6">
56
  <div class="max-w-4xl mx-auto">
57
- <div class="card p-6 bg-white">
58
  <div class="flex flex-col md:flex-row items-center justify-between mb-6">
59
- <h1 class="text-3xl font-bold text-black mb-2 md:mb-0">LOKI.AI IMAGE PLAYGROUND</h1>
60
- <div class="pulse bg-black text-white px-3 py-1 rounded-full text-sm">Powered by LOKI.AI</div>
 
 
 
 
 
61
  </div>
62
 
63
  <div class="space-y-4">
64
  <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
65
  <div>
66
- <label for="model" class="block text-sm font-medium text-gray-700 mb-1">Select Model</label>
67
  <div class="relative">
68
- <select id="model" class="block w-full px-3 py-2 bg-gray-50 border border-gray-200 rounded-lg focus:outline-none focus:ring-1 focus:ring-black appearance-none">
69
  <option value="Flux Realism">Flux Realism</option>
70
  <option value="Flux Pro Ultra">Flux Pro Ultra</option>
71
  <option value="grok-2-aurora">grok-2-aurora</option>
@@ -77,7 +123,7 @@
77
  <option value="sdxl-lightning-4step">sdxl-lightning-4step</option>
78
  <option value="dall-e-3">dall-e-3</option>
79
  </select>
80
- <div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-gray-700">
81
  <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
82
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
83
  </svg>
@@ -85,50 +131,59 @@
85
  </div>
86
  </div>
87
  <div>
88
- <label for="prompt" class="block text-sm font-medium text-gray-700 mb-1">Enter Prompt</label>
89
- <input type="text" id="prompt" placeholder="Describe what you want to see..." class="block w-full px-3 py-2 bg-gray-50 border border-gray-200 rounded-lg focus:outline-none focus:ring-1 focus:ring-black" value="sky">
90
  </div>
91
  </div>
92
 
93
- <div class="flex justify-center mt-2">
94
- <button id="generate" class="bg-black text-white px-6 py-2 rounded-lg font-medium hover:bg-gray-800">
95
- Generate Image
96
- </button>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
  </div>
98
 
99
- <div id="result" class="mt-4 hidden">
100
  <div class="text-center mb-4">
101
- <h2 class="text-lg font-medium">Your Creation</h2>
102
- <p class="text-sm text-gray-500">Created with <span id="model-used"></span></p>
103
  </div>
104
- <div class="image-container mx-auto max-w-lg">
105
- <img id="generated-image" class="w-full h-auto shadow-md" src="" alt="Generated image">
106
- </div>
107
- <div class="mt-4 text-center">
108
- <button id="download" class="bg-gray-100 hover:bg-gray-200 text-black px-4 py-2 rounded-lg font-medium">
109
- <span class="flex items-center justify-center">
110
- <svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
111
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"></path>
112
- </svg>
113
- Download
114
- </span>
115
- </button>
116
  </div>
117
  </div>
118
 
119
  <div id="loading" class="flex flex-col items-center justify-center py-6 hidden">
120
  <div class="loading mb-3"></div>
121
- <p class="text-gray-600 text-sm">Creating your image...</p>
122
  </div>
123
 
124
- <div id="error" class="bg-red-50 text-red-700 p-3 rounded-lg hidden">
125
  <p class="font-medium">Oops! Something went wrong.</p>
126
  <p class="text-sm">Please try again or check your connection.</p>
127
  </div>
128
  </div>
129
  </div>
130
 
131
- <div class="text-center text-gray-400 text-xs mt-4">
132
  © 2025 LOKI.AI IMAGE PLAYGROUND | All rights reserved
133
  </div>
134
  </div>
@@ -136,20 +191,38 @@
136
  <script>
137
  document.addEventListener('DOMContentLoaded', () => {
138
  // Elements
 
139
  const generateBtn = document.getElementById('generate');
140
- const downloadBtn = document.getElementById('download');
141
  const promptInput = document.getElementById('prompt');
142
  const modelSelect = document.getElementById('model');
 
 
143
  const resultDiv = document.getElementById('result');
144
  const loadingDiv = document.getElementById('loading');
145
  const errorDiv = document.getElementById('error');
146
- const generatedImage = document.getElementById('generated-image');
147
  const modelUsed = document.getElementById('model-used');
148
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
149
  // Generate image
150
  generateBtn.addEventListener('click', async () => {
151
  const prompt = promptInput.value.trim();
152
  const model = modelSelect.value;
 
 
153
 
154
  if (!prompt) {
155
  promptInput.style.borderColor = 'red';
@@ -174,8 +247,8 @@
174
  body: JSON.stringify({
175
  model: model,
176
  prompt: prompt,
177
- size: 1024,
178
- number: 1
179
  })
180
  });
181
 
@@ -190,9 +263,48 @@
190
  resultDiv.classList.remove('hidden');
191
  modelUsed.textContent = model;
192
 
193
- // Assuming the response has an images array with base64 or URLs
 
 
 
194
  if (data.images && data.images.length > 0) {
195
- generatedImage.src = data.images[0];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
196
  }
197
 
198
  } catch (error) {
@@ -204,18 +316,6 @@
204
  }
205
  });
206
 
207
- // Download image
208
- downloadBtn.addEventListener('click', () => {
209
- if (!generatedImage.src) return;
210
-
211
- const a = document.createElement('a');
212
- a.href = generatedImage.src;
213
- a.download = `loki-ai-${new Date().getTime()}.png`;
214
- document.body.appendChild(a);
215
- a.click();
216
- document.body.removeChild(a);
217
- });
218
-
219
  // Enter key to generate
220
  promptInput.addEventListener('keypress', (e) => {
221
  if (e.key === 'Enter') {
 
1
  <!DOCTYPE html>
2
+ <html lang="en" class="light">
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
 
11
  font-family: 'DM Sans', sans-serif;
12
  }
13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  .loading {
15
  width: 40px;
16
  height: 40px;
 
20
  animation: rotation 1.2s linear infinite;
21
  }
22
 
23
+ .dark .loading {
24
+ border-color: #333;
25
+ border-bottom-color: #fff;
26
+ }
27
+
28
  @keyframes rotation {
29
  0% { transform: rotate(0deg); }
30
  100% { transform: rotate(360deg); }
 
34
  border-radius: 8px;
35
  overflow: hidden;
36
  }
37
+
38
+ .theme-toggle {
39
+ position: relative;
40
+ width: 48px;
41
+ height: 24px;
42
+ border-radius: 12px;
43
+ background-color: #e5e5e5;
44
+ cursor: pointer;
45
+ transition: background-color 0.3s;
46
+ }
47
+
48
+ .dark .theme-toggle {
49
+ background-color: #555;
50
+ }
51
+
52
+ .toggle-thumb {
53
+ position: absolute;
54
+ top: 2px;
55
+ left: 2px;
56
+ width: 20px;
57
+ height: 20px;
58
+ border-radius: 50%;
59
+ background-color: white;
60
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
61
+ transition: transform 0.3s;
62
+ }
63
+
64
+ .dark .toggle-thumb {
65
+ transform: translateX(24px);
66
+ }
67
+
68
+ .dark {
69
+ background-color: #121212;
70
+ color: #f5f5f5;
71
+ }
72
+
73
+ .dark .card {
74
+ background-color: #1e1e1e;
75
+ border-color: rgba(255, 255, 255, 0.1);
76
+ }
77
+
78
+ .dark .form-input {
79
+ background-color: #2d2d2d;
80
+ color: #f5f5f5;
81
+ border-color: #444;
82
+ }
83
+
84
+ .dark .btn-primary {
85
+ background-color: #f5f5f5;
86
+ color: #121212;
87
+ }
88
+
89
+ .dark .btn-secondary {
90
+ background-color: #2d2d2d;
91
+ color: #f5f5f5;
92
+ border: 1px solid #444;
93
+ }
94
  </style>
95
  </head>
96
+ <body class="p-4 md:p-6 bg-gray-50 dark:bg-gray-900 transition-colors duration-200">
97
  <div class="max-w-4xl mx-auto">
98
+ <div class="bg-white dark:bg-gray-800 rounded-lg shadow-md p-6 transition-colors duration-200">
99
  <div class="flex flex-col md:flex-row items-center justify-between mb-6">
100
+ <h1 class="text-3xl font-bold text-black dark:text-white mb-2 md:mb-0">LOKI.AI IMAGE PLAYGROUND</h1>
101
+ <div class="flex items-center space-x-4">
102
+ <div class="text-sm text-gray-500 dark:text-gray-400">Theme</div>
103
+ <div id="theme-toggle" class="theme-toggle">
104
+ <div class="toggle-thumb"></div>
105
+ </div>
106
+ </div>
107
  </div>
108
 
109
  <div class="space-y-4">
110
  <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
111
  <div>
112
+ <label for="model" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Select Model</label>
113
  <div class="relative">
114
+ <select id="model" class="form-input block w-full px-3 py-2 bg-gray-50 dark:bg-gray-700 border border-gray-200 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-1 focus:ring-black dark:focus:ring-white text-gray-900 dark:text-white appearance-none">
115
  <option value="Flux Realism">Flux Realism</option>
116
  <option value="Flux Pro Ultra">Flux Pro Ultra</option>
117
  <option value="grok-2-aurora">grok-2-aurora</option>
 
123
  <option value="sdxl-lightning-4step">sdxl-lightning-4step</option>
124
  <option value="dall-e-3">dall-e-3</option>
125
  </select>
126
+ <div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-gray-700 dark:text-gray-300">
127
  <svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
128
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
129
  </svg>
 
131
  </div>
132
  </div>
133
  <div>
134
+ <label for="prompt" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Enter Prompt</label>
135
+ <input type="text" id="prompt" placeholder="Describe what you want to see..." class="form-input block w-full px-3 py-2 bg-gray-50 dark:bg-gray-700 border border-gray-200 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-1 focus:ring-black dark:focus:ring-white text-gray-900 dark:text-white" value="sky">
136
  </div>
137
  </div>
138
 
139
+ <div class="grid grid-cols-1 md:grid-cols-3 gap-4 mt-2">
140
+ <div>
141
+ <label for="image-size" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Image Size</label>
142
+ <select id="image-size" class="form-input block w-full px-3 py-2 bg-gray-50 dark:bg-gray-700 border border-gray-200 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-1 focus:ring-black dark:focus:ring-white text-gray-900 dark:text-white appearance-none">
143
+ <option value="512">512 x 512</option>
144
+ <option value="768">768 x 768</option>
145
+ <option value="1024" selected>1024 x 1024</option>
146
+ <option value="1536">1536 x 1536</option>
147
+ </select>
148
+ </div>
149
+ <div>
150
+ <label for="image-count" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Number of Images</label>
151
+ <select id="image-count" class="form-input block w-full px-3 py-2 bg-gray-50 dark:bg-gray-700 border border-gray-200 dark:border-gray-600 rounded-lg focus:outline-none focus:ring-1 focus:ring-black dark:focus:ring-white text-gray-900 dark:text-white appearance-none">
152
+ <option value="1" selected>1</option>
153
+ <option value="2">2</option>
154
+ <option value="4">4</option>
155
+ </select>
156
+ </div>
157
+ <div class="flex items-end">
158
+ <button id="generate" class="btn-primary w-full bg-black dark:bg-white text-white dark:text-black px-6 py-2 rounded-lg font-medium hover:bg-gray-800 dark:hover:bg-gray-200 transition">
159
+ Generate Image
160
+ </button>
161
+ </div>
162
  </div>
163
 
164
+ <div id="result" class="mt-6 hidden">
165
  <div class="text-center mb-4">
166
+ <h2 class="text-lg font-medium dark:text-white">Your Creation</h2>
167
+ <p class="text-sm text-gray-500 dark:text-gray-400">Created with <span id="model-used"></span></p>
168
  </div>
169
+ <div id="images-container" class="grid grid-cols-1 md:grid-cols-2 gap-4">
170
+ <!-- Images will be inserted here dynamically -->
 
 
 
 
 
 
 
 
 
 
171
  </div>
172
  </div>
173
 
174
  <div id="loading" class="flex flex-col items-center justify-center py-6 hidden">
175
  <div class="loading mb-3"></div>
176
+ <p class="text-gray-600 dark:text-gray-400 text-sm">Creating your image...</p>
177
  </div>
178
 
179
+ <div id="error" class="bg-red-50 dark:bg-red-900/30 text-red-700 dark:text-red-400 p-3 rounded-lg hidden">
180
  <p class="font-medium">Oops! Something went wrong.</p>
181
  <p class="text-sm">Please try again or check your connection.</p>
182
  </div>
183
  </div>
184
  </div>
185
 
186
+ <div class="text-center text-gray-400 dark:text-gray-600 text-xs mt-4">
187
  © 2025 LOKI.AI IMAGE PLAYGROUND | All rights reserved
188
  </div>
189
  </div>
 
191
  <script>
192
  document.addEventListener('DOMContentLoaded', () => {
193
  // Elements
194
+ const themeToggle = document.getElementById('theme-toggle');
195
  const generateBtn = document.getElementById('generate');
 
196
  const promptInput = document.getElementById('prompt');
197
  const modelSelect = document.getElementById('model');
198
+ const imageSizeSelect = document.getElementById('image-size');
199
+ const imageCountSelect = document.getElementById('image-count');
200
  const resultDiv = document.getElementById('result');
201
  const loadingDiv = document.getElementById('loading');
202
  const errorDiv = document.getElementById('error');
203
+ const imagesContainer = document.getElementById('images-container');
204
  const modelUsed = document.getElementById('model-used');
205
 
206
+ // Theme Toggle
207
+ themeToggle.addEventListener('click', () => {
208
+ document.documentElement.classList.toggle('dark');
209
+ localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light');
210
+ });
211
+
212
+ // Check for saved theme preference
213
+ if (localStorage.getItem('theme') === 'dark' ||
214
+ (!localStorage.getItem('theme') && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
215
+ document.documentElement.classList.add('dark');
216
+ } else {
217
+ document.documentElement.classList.remove('dark');
218
+ }
219
+
220
  // Generate image
221
  generateBtn.addEventListener('click', async () => {
222
  const prompt = promptInput.value.trim();
223
  const model = modelSelect.value;
224
+ const size = parseInt(imageSizeSelect.value);
225
+ const number = parseInt(imageCountSelect.value);
226
 
227
  if (!prompt) {
228
  promptInput.style.borderColor = 'red';
 
247
  body: JSON.stringify({
248
  model: model,
249
  prompt: prompt,
250
+ size: size,
251
+ number: number
252
  })
253
  });
254
 
 
263
  resultDiv.classList.remove('hidden');
264
  modelUsed.textContent = model;
265
 
266
+ // Clear previous images
267
+ imagesContainer.innerHTML = '';
268
+
269
+ // Add generated images
270
  if (data.images && data.images.length > 0) {
271
+ // Set grid columns based on number of images
272
+ if (number > 1) {
273
+ imagesContainer.className = `grid grid-cols-1 ${number > 1 ? 'md:grid-cols-2' : ''} gap-4`;
274
+ } else {
275
+ imagesContainer.className = 'mx-auto max-w-lg';
276
+ }
277
+
278
+ data.images.forEach((imgSrc, index) => {
279
+ const imgContainer = document.createElement('div');
280
+ imgContainer.className = 'image-container relative';
281
+
282
+ const img = document.createElement('img');
283
+ img.src = imgSrc;
284
+ img.className = 'w-full h-auto shadow-md';
285
+ img.alt = `Generated image ${index + 1}`;
286
+
287
+ const downloadBtn = document.createElement('button');
288
+ downloadBtn.className = 'btn-secondary absolute bottom-3 right-3 bg-white dark:bg-gray-800 text-black dark:text-white p-2 rounded-full shadow-lg';
289
+ downloadBtn.innerHTML = `
290
+ <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
291
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"></path>
292
+ </svg>
293
+ `;
294
+
295
+ downloadBtn.addEventListener('click', () => {
296
+ const a = document.createElement('a');
297
+ a.href = imgSrc;
298
+ a.download = `loki-ai-${model}-${index + 1}-${new Date().getTime()}.png`;
299
+ document.body.appendChild(a);
300
+ a.click();
301
+ document.body.removeChild(a);
302
+ });
303
+
304
+ imgContainer.appendChild(img);
305
+ imgContainer.appendChild(downloadBtn);
306
+ imagesContainer.appendChild(imgContainer);
307
+ });
308
  }
309
 
310
  } catch (error) {
 
316
  }
317
  });
318
 
 
 
 
 
 
 
 
 
 
 
 
 
319
  // Enter key to generate
320
  promptInput.addEventListener('keypress', (e) => {
321
  if (e.key === 'Enter') {