ParthSadaria commited on
Commit
5f424f1
·
verified ·
1 Parent(s): ca92d63

Create image-playground.html

Browse files
Files changed (1) hide show
  1. image-playground.html +327 -0
image-playground.html ADDED
@@ -0,0 +1,327 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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>LOKI.AI IMAGE PLAYGROUND</title>
7
+ <link href="https://fonts.googleapis.com/css2?family=DM+Sans:ital,wght@0,400;0,500;0,700;1,400&display=swap" rel="stylesheet">
8
+ <script src="https://cdn.tailwindcss.com"></script>
9
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
10
+ <style>
11
+ * {
12
+ font-family: 'DM Sans', sans-serif;
13
+ transition: all 0.3s ease;
14
+ }
15
+
16
+ body {
17
+ background: linear-gradient(135deg, #ffffff 0%, #f5f5f5 100%);
18
+ min-height: 100vh;
19
+ }
20
+
21
+ .card {
22
+ backdrop-filter: blur(10px);
23
+ border: 1px solid rgba(255, 255, 255, 0.3);
24
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
25
+ border-radius: 16px;
26
+ }
27
+
28
+ .pulse {
29
+ animation: pulse 1.5s infinite;
30
+ }
31
+
32
+ @keyframes pulse {
33
+ 0% { transform: scale(0.95); }
34
+ 50% { transform: scale(1); }
35
+ 100% { transform: scale(0.95); }
36
+ }
37
+
38
+ .loading {
39
+ width: 48px;
40
+ height: 48px;
41
+ border: 5px solid #f5f5f5;
42
+ border-bottom-color: #000;
43
+ border-radius: 50%;
44
+ animation: rotation 1s linear infinite;
45
+ }
46
+
47
+ @keyframes rotation {
48
+ 0% { transform: rotate(0deg); }
49
+ 100% { transform: rotate(360deg); }
50
+ }
51
+
52
+ .image-container {
53
+ overflow: hidden;
54
+ border-radius: 12px;
55
+ }
56
+
57
+ .image-container img {
58
+ transition: transform 0.5s ease;
59
+ }
60
+
61
+ .image-container:hover img {
62
+ transform: scale(1.05);
63
+ }
64
+
65
+ button {
66
+ position: relative;
67
+ overflow: hidden;
68
+ }
69
+
70
+ button:after {
71
+ content: '';
72
+ position: absolute;
73
+ top: 50%;
74
+ left: 50%;
75
+ width: 100%;
76
+ height: 100%;
77
+ background: rgba(255, 255, 255, 0.3);
78
+ border-radius: 50%;
79
+ transform: scale(0);
80
+ transition: transform 0.5s;
81
+ pointer-events: none;
82
+ }
83
+
84
+ button:active:after {
85
+ transform: scale(3);
86
+ opacity: 0;
87
+ transition: transform 0.5s, opacity 0.3s;
88
+ }
89
+ </style>
90
+ </head>
91
+ <body class="p-4 md:p-8">
92
+ <div class="max-w-4xl mx-auto">
93
+ <div class="card p-6 md:p-8 bg-white/80">
94
+ <div class="flex flex-col md:flex-row items-center justify-between mb-8">
95
+ <h1 class="text-3xl md:text-4xl font-bold bg-gradient-to-r from-black to-gray-700 bg-clip-text text-transparent mb-4 md:mb-0">LOKI.AI IMAGE PLAYGROUND</h1>
96
+ <div class="pulse bg-black text-white px-4 py-1 rounded-full text-sm">Powered by LOKI.AI</div>
97
+ </div>
98
+
99
+ <div class="space-y-6">
100
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
101
+ <div>
102
+ <label for="model" class="block text-sm font-medium text-gray-700 mb-2">Select Model</label>
103
+ <div class="relative">
104
+ <select id="model" class="block w-full px-4 py-3 bg-gray-50 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-black appearance-none">
105
+ <option value="Flux Realism">Flux Realism</option>
106
+ <option value="Flux Pro Ultra">Flux Pro Ultra</option>
107
+ <option value="grok-2-aurora">grok-2-aurora</option>
108
+ <option value="Flux Pro">Flux Pro</option>
109
+ <option value="Flux Pro Ultra Raw">Flux Pro Ultra Raw</option>
110
+ <option value="Flux Dev">Flux Dev</option>
111
+ <option value="Flux Schnell">Flux Schnell</option>
112
+ <option value="stable-diffusion-3-large-turbo">stable-diffusion-3-large-turbo</option>
113
+ <option value="sdxl-lightning-4step">sdxl-lightning-4step</option>
114
+ <option value="dall-e-3">dall-e-3</option>
115
+ </select>
116
+ <div class="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-gray-700">
117
+ <svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
118
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
119
+ </svg>
120
+ </div>
121
+ </div>
122
+ </div>
123
+ <div>
124
+ <label for="prompt" class="block text-sm font-medium text-gray-700 mb-2">Enter Prompt</label>
125
+ <input type="text" id="prompt" placeholder="Describe what you want to see..." class="block w-full px-4 py-3 bg-gray-50 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-black" value="sky">
126
+ </div>
127
+ </div>
128
+
129
+ <div class="flex flex-col items-center justify-center space-y-4">
130
+ <button id="generate" class="w-full md:w-auto bg-black text-white px-8 py-3 rounded-lg font-medium hover:bg-gray-800 transform hover:scale-105 transition-all">
131
+ Generate Image
132
+ </button>
133
+ <div id="status" class="text-sm text-gray-500 hidden">Processing your request...</div>
134
+ </div>
135
+
136
+ <div id="result" class="mt-6 hidden">
137
+ <div class="text-center mb-6">
138
+ <h2 class="text-xl font-medium">Your Creation</h2>
139
+ <p class="text-sm text-gray-500">Created with <span id="model-used"></span></p>
140
+ </div>
141
+ <div class="image-container mx-auto max-w-lg">
142
+ <img id="generated-image" class="w-full h-auto object-cover shadow-lg" src="" alt="Generated image">
143
+ </div>
144
+ <div class="mt-4 text-center">
145
+ <button id="download" class="bg-gray-200 hover:bg-gray-300 text-black px-6 py-2 rounded-lg font-medium mt-4 transform hover:scale-105 transition-all">
146
+ <span class="flex items-center justify-center">
147
+ <svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
148
+ <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>
149
+ </svg>
150
+ Download
151
+ </span>
152
+ </button>
153
+ </div>
154
+ </div>
155
+
156
+ <div id="loading" class="flex flex-col items-center justify-center py-10 hidden">
157
+ <div class="loading mb-4"></div>
158
+ <p class="text-gray-600">Creating your masterpiece...</p>
159
+ </div>
160
+
161
+ <div id="error" class="bg-red-50 text-red-800 p-4 rounded-lg hidden">
162
+ <p class="font-medium">Oops! Something went wrong.</p>
163
+ <p class="text-sm">Please try again or check your connection.</p>
164
+ </div>
165
+ </div>
166
+ </div>
167
+
168
+ <div class="text-center text-gray-500 text-xs mt-6">
169
+ © 2025 LOKI.AI IMAGE PLAYGROUND | All rights reserved
170
+ </div>
171
+ </div>
172
+
173
+ <script>
174
+ document.addEventListener('DOMContentLoaded', () => {
175
+ // Elements
176
+ const generateBtn = document.getElementById('generate');
177
+ const downloadBtn = document.getElementById('download');
178
+ const promptInput = document.getElementById('prompt');
179
+ const modelSelect = document.getElementById('model');
180
+ const resultDiv = document.getElementById('result');
181
+ const loadingDiv = document.getElementById('loading');
182
+ const errorDiv = document.getElementById('error');
183
+ const statusDiv = document.getElementById('status');
184
+ const generatedImage = document.getElementById('generated-image');
185
+ const modelUsed = document.getElementById('model-used');
186
+
187
+ // Animations with GSAP
188
+ gsap.from('.card', {
189
+ duration: 1,
190
+ opacity: 0,
191
+ y: 50,
192
+ ease: 'power3.out'
193
+ });
194
+
195
+ gsap.from('h1', {
196
+ duration: 1.2,
197
+ opacity: 0,
198
+ y: 20,
199
+ delay: 0.3,
200
+ ease: 'power3.out'
201
+ });
202
+
203
+ const staggerItems = [modelSelect, promptInput, generateBtn];
204
+ gsap.from(staggerItems, {
205
+ duration: 0.8,
206
+ opacity: 0,
207
+ y: 20,
208
+ stagger: 0.2,
209
+ delay: 0.5,
210
+ ease: 'power3.out'
211
+ });
212
+
213
+ // Generate image
214
+ generateBtn.addEventListener('click', async () => {
215
+ const prompt = promptInput.value.trim();
216
+ const model = modelSelect.value;
217
+
218
+ if (!prompt) {
219
+ promptInput.classList.add('ring-2', 'ring-red-500');
220
+ setTimeout(() => {
221
+ promptInput.classList.remove('ring-2', 'ring-red-500');
222
+ }, 2000);
223
+ return;
224
+ }
225
+
226
+ // Show loading state
227
+ resultDiv.classList.add('hidden');
228
+ errorDiv.classList.add('hidden');
229
+ loadingDiv.classList.remove('hidden');
230
+ statusDiv.classList.remove('hidden');
231
+ generateBtn.disabled = true;
232
+
233
+ try {
234
+ const response = await fetch('https://parthsadaria-lokiai.hf.space/images/generations', {
235
+ method: 'POST',
236
+ headers: {
237
+ 'Content-Type': 'application/json',
238
+ },
239
+ body: JSON.stringify({
240
+ model: model,
241
+ prompt: prompt,
242
+ size: 1024,
243
+ number: 1
244
+ })
245
+ });
246
+
247
+ if (!response.ok) {
248
+ throw new Error('API request failed');
249
+ }
250
+
251
+ const data = await response.json();
252
+
253
+ // Display result
254
+ loadingDiv.classList.add('hidden');
255
+ resultDiv.classList.remove('hidden');
256
+ modelUsed.textContent = model;
257
+
258
+ // Assuming the response has an images array with base64 or URLs
259
+ if (data.images && data.images.length > 0) {
260
+ generatedImage.src = data.images[0];
261
+
262
+ // Animate the image appearance
263
+ gsap.from('#generated-image', {
264
+ duration: 1,
265
+ opacity: 0,
266
+ scale: 0.9,
267
+ ease: 'power3.out'
268
+ });
269
+ }
270
+
271
+ } catch (error) {
272
+ console.error('Error:', error);
273
+ loadingDiv.classList.add('hidden');
274
+ errorDiv.classList.remove('hidden');
275
+ } finally {
276
+ generateBtn.disabled = false;
277
+ statusDiv.classList.add('hidden');
278
+ }
279
+ });
280
+
281
+ // Download image
282
+ downloadBtn.addEventListener('click', () => {
283
+ if (!generatedImage.src) return;
284
+
285
+ const a = document.createElement('a');
286
+ a.href = generatedImage.src;
287
+ a.download = `loki-ai-${new Date().getTime()}.png`;
288
+ document.body.appendChild(a);
289
+ a.click();
290
+ document.body.removeChild(a);
291
+
292
+ // Animation feedback
293
+ gsap.to('#download', {
294
+ duration: 0.3,
295
+ scale: 1.1,
296
+ yoyo: true,
297
+ repeat: 1
298
+ });
299
+ });
300
+
301
+ // Add input animations
302
+ promptInput.addEventListener('focus', () => {
303
+ gsap.to(promptInput, {
304
+ duration: 0.3,
305
+ scale: 1.02,
306
+ ease: 'power2.out'
307
+ });
308
+ });
309
+
310
+ promptInput.addEventListener('blur', () => {
311
+ gsap.to(promptInput, {
312
+ duration: 0.3,
313
+ scale: 1,
314
+ ease: 'power2.in'
315
+ });
316
+ });
317
+
318
+ // Enter key to generate
319
+ promptInput.addEventListener('keypress', (e) => {
320
+ if (e.key === 'Enter') {
321
+ generateBtn.click();
322
+ }
323
+ });
324
+ });
325
+ </script>
326
+ </body>
327
+ </html>