yasirme commited on
Commit
111b0ec
·
verified ·
1 Parent(s): 7a6dbf7

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +443 -18
index.html CHANGED
@@ -1,19 +1,444 @@
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" />
6
+ <title>Minimal AI Image Generator</title>
7
+ <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600&display=swap" rel="stylesheet">
8
+ <style>
9
+ *, *::before, *::after { box-sizing: border-box; }
10
+ html, body { height: 100%; margin: 0; padding: 0; font-family: 'Poppins', sans-serif; -webkit-font-smoothing:antialiased; -moz-osx-font-smoothing:grayscale; }
11
+ body { background: radial-gradient(circle at 20% 20%, rgba(140,60,200,0.08), transparent 40%), radial-gradient(circle at 80% 80%, rgba(200,60,255,0.05), transparent 40%), #000; color:#fff; overflow: hidden; }
12
+
13
+ .topbar {
14
+ position: fixed;
15
+ top: 0;
16
+ left: 0;
17
+ right: 0;
18
+ height: 56px;
19
+ display: flex;
20
+ align-items: center;
21
+ justify-content: space-between;
22
+ padding: 0 16px;
23
+ gap: 12px;
24
+ z-index: 1000;
25
+ background: transparent;
26
+ }
27
+ .btn-small {
28
+ background: #141414;
29
+ border-radius: 10px;
30
+ padding: 8px 12px;
31
+ font-size: 13px;
32
+ color: #fff;
33
+ display:inline-flex;
34
+ align-items:center;
35
+ gap:10px;
36
+ border:1px solid rgba(255,255,255,0.03);
37
+ }
38
+ .btn-small img { width:14px; height:14px; display:block; }
39
+
40
+ .container {
41
+ width: 70%;
42
+ max-width: 1100px;
43
+ margin: 5em auto 16px;
44
+ padding: 0 12px;
45
+ display: flex;
46
+ flex-direction: column;
47
+ gap: 12px;
48
+ position: relative;
49
+ }
50
+ @media (max-width: 768px) {
51
+ .container { width: 100%; padding: 0 12px; margin-top:5em; }
52
+ }
53
+
54
+ .input-row {
55
+ display:flex;
56
+ gap:10px;
57
+ align-items:flex-start;
58
+ }
59
+ textarea#prompt {
60
+ flex:1;
61
+ min-width:0;
62
+ max-height:250px;
63
+ height:56px;
64
+ resize:none;
65
+ border-radius:12px;
66
+ padding:12px;
67
+ background:#0e0e0e;
68
+ border:1px solid rgba(255,255,255,0.03);
69
+ color:#fff;
70
+ font-size:14px;
71
+ line-height:1.35;
72
+ overflow:auto;
73
+ outline:none;
74
+ }
75
+ .generate-btn {
76
+ background: linear-gradient(90deg,#ff93e9,#9b7cff);
77
+ border:none;
78
+ border-radius:12px;
79
+ padding:12px 18px;
80
+ font-size:14px;
81
+ cursor:pointer;
82
+ color:#fff;
83
+ min-height:56px;
84
+ display:inline-flex;
85
+ align-items:center;
86
+ justify-content:center;
87
+ transition:opacity .15s;
88
+ }
89
+ .generate-btn[disabled] { opacity:0.6; cursor:default; }
90
+
91
+ .options-row {
92
+ display:flex;
93
+ justify-content:space-between;
94
+ align-items:center;
95
+ }
96
+ .left-group, .right-group { display:flex; gap:8px; align-items:center; }
97
+
98
+ .modal-backdrop {
99
+ display:none;
100
+ position: fixed;
101
+ inset: 0;
102
+ background: rgba(0,0,0,0.72);
103
+ align-items: center;
104
+ justify-content: center;
105
+ padding: 20px;
106
+ z-index: 2000;
107
+ }
108
+ .modal {
109
+ width: 100%;
110
+ max-width: 720px;
111
+ background: #0f0f0f;
112
+ border-radius: 12px;
113
+ padding: 18px;
114
+ box-shadow: 0 10px 40px rgba(0,0,0,0.6);
115
+ color: #fff;
116
+ }
117
+ @media (max-width:420px) {
118
+ .modal { padding: 14px; max-width: calc(100% - 12px); border-radius: 10px; }
119
+ }
120
+
121
+ .styles-grid {
122
+ display:grid;
123
+ grid-template-columns: repeat(2, 1fr);
124
+ gap:10px;
125
+ margin-top:12px;
126
+ }
127
+ .style-card {
128
+ background:#101010;
129
+ border-radius:10px;
130
+ overflow:hidden;
131
+ cursor:pointer;
132
+ text-align:center;
133
+ border:2px solid transparent;
134
+ padding-bottom:8px;
135
+ font-size:13px;
136
+ }
137
+ .style-card img { width:100%; height:72px; object-fit:cover; display:block; }
138
+ .style-card.selected { border-color:#ff93e9; box-shadow: 0 8px 30px rgba(155,124,255,0.06); }
139
+
140
+ .settings-row { display:flex; gap:12px; align-items:center; margin-top:10px; flex-wrap:wrap; }
141
+ .settings-row label { font-size:14px; display:flex; gap:8px; align-items:center; color:#eaeaea; }
142
+ .settings-row input[type="number"], .settings-row select { background:#0c0c0c; border:1px solid rgba(255,255,255,0.04); color:#fff; padding:6px 8px; border-radius:8px; font-size:14px; min-width:80px; }
143
+
144
+ .modal-actions { margin-top:14px; display:flex; justify-content:flex-end; gap:10px; }
145
+ .modal-actions button { background:#1a1a1a; border-radius:10px; padding:9px 12px; font-size:14px; color:#fff; border:1px solid rgba(255,255,255,0.03); cursor:pointer; }
146
+
147
+ #images {
148
+ margin-top:8px;
149
+ display:flex;
150
+ gap:12px;
151
+ flex-wrap:wrap;
152
+ justify-content:center;
153
+ align-items:flex-start;
154
+ overflow:auto;
155
+ padding:10px;
156
+ border-radius:10px;
157
+ background: linear-gradient(180deg, rgba(255,255,255,0.01), transparent);
158
+ border:1px solid rgba(255,255,255,0.02);
159
+ max-height: calc(100vh - 5em - 220px);
160
+ }
161
+
162
+ .image-card {
163
+ background:#0b0b0b;
164
+ border-radius:12px;
165
+ padding:8px;
166
+ min-height:120px;
167
+ width: min(350px, 90vw);
168
+ box-shadow: 0 10px 30px rgba(0,0,0,0.6);
169
+ border:1px solid rgba(255,255,255,0.02);
170
+ display:flex;
171
+ align-items:center;
172
+ justify-content:center;
173
+ }
174
+ .image-card img { width:100%; height:auto; display:block; border-radius:8px; }
175
+
176
+ .loader { border:3px solid #222; border-top:3px solid #ff93e9; border-radius:50%; width:22px; height:22px; animation:spin 1s linear infinite; }
177
+ @keyframes spin { 0%{ transform:rotate(0) } 100%{ transform:rotate(360deg) } }
178
+
179
+ .muted { color:#9b9b9b; font-size:13px; }
180
+
181
+ .row { display:flex; gap:10px; align-items:center; }
182
+ .note { font-size:13px; color:#cfcfcf; margin-top:6px; }
183
+ </style>
184
+ </head>
185
+ <body>
186
+
187
+ <div class="topbar" role="banner">
188
+ <div class="btn-small" onclick="window.open('https://discord.gg/QjyD579HSn') ">Discord</div>
189
+ <a class="btn-small" href="https://buymeacoffee.com/xyaiman" target="_blank" rel="noopener">
190
+ <img src="https://cdn.buymeacoffee.com/buttons/bmc-new-btn-logo.svg" alt="coffee">
191
+ <span>Buy me a coffee</span>
192
+ </a>
193
+ </div>
194
+
195
+ <div class="container" role="main">
196
+ <div class="input-row" role="search">
197
+ <textarea id="prompt" placeholder="Enter your prompt..." aria-label="Prompt"></textarea>
198
+ <button id="generateBtn" class="generate-btn" aria-label="Generate">Generate</button>
199
+ </div>
200
+
201
+ <div class="options-row">
202
+ <div class="left-group">
203
+ <div id="styleBtn" class="btn-small" aria-haspopup="dialog">🎨 Style</div>
204
+ </div>
205
+ <div class="right-group">
206
+ <div id="settingsBtn" class="btn-small" aria-haspopup="dialog">⚙️ Settings</div>
207
+ </div>
208
+ </div>
209
+
210
+ <div class="note">Generated images (scroll this pane). New images appear at the top.</div>
211
+
212
+ <div id="images" aria-live="polite"></div>
213
+ </div>
214
+
215
+ <div id="styleModal" class="modal-backdrop" role="dialog" aria-modal="true" aria-hidden="true">
216
+ <div class="modal" role="document">
217
+ <h2 style="margin:0 0 6px 0;">Choose a style</h2>
218
+ <div class="note">Click a style — it will be applied to the request (not shown in the input).</div>
219
+
220
+ <div class="styles-grid" id="stylesGrid">
221
+ <div class="style-card selected" data-name="none"><img src="none.jpg" alt="No style"><div>No style</div></div>
222
+ <div class="style-card" data-name="cinema"><img src="https://xyplon.web.app/assets/Cinematic.jpeg" alt="Cinema"><div>Cinema</div></div>
223
+ <div class="style-card" data-name="realistic"><img src="https://xyplon.web.app/assets/Realistic.jpeg" alt="Realistic"><div>Realistic</div></div>
224
+ <div class="style-card" data-name="photography"><img src="https://xyplon.web.app/assets/Photography.jpeg" alt="Photography"><div>Photography</div></div>
225
+ <div class="style-card" data-name="fantasy"><img src="https://xyplon.web.app/assets/Digital.jpeg" alt="Fantasy"><div>Fantasy</div></div>
226
+ </div>
227
+
228
+ <div class="modal-actions">
229
+ <button id="closeStyle">Close</button>
230
+ </div>
231
+ </div>
232
+ </div>
233
+
234
+ <div id="settingsModal" class="modal-backdrop" role="dialog" aria-modal="true" aria-hidden="true">
235
+ <div class="modal" role="document">
236
+ <h2 style="margin:0 0 6px 0;">API Settings</h2>
237
+
238
+ <div class="settings-row">
239
+ <label>Model:
240
+ <select id="model">
241
+ <option value="flux">flux</option>
242
+ <option value="turbo">turbo (uncensored) </option>
243
+ </select>
244
+ </label>
245
+
246
+ <label>Width:
247
+ <input id="width" type="number" min="64" max="2048" value="1024" />
248
+ </label>
249
+
250
+ <label>Height:
251
+ <input id="height" type="number" min="64" max="2048" value="1024" />
252
+ </label>
253
+
254
+ <label>Enhance:
255
+ <input id="enhance" type="checkbox" />
256
+ </label>
257
+
258
+ <label>Seed:
259
+ <input id="seed" type="number" value="42" />
260
+ </label>
261
+
262
+ <label style="display:flex;align-items:center;gap:6px;">
263
+ <input id="randomSeed" type="checkbox" checked /> Random
264
+ </label>
265
+ </div>
266
+
267
+ <div class="modal-actions">
268
+ <button id="closeSettings">Close</button>
269
+ <button id="saveSettings">Save</button>
270
+ </div>
271
+ </div>
272
+ </div>
273
+
274
+ <script>
275
+ const baseUrl = 'https://image.pollinations.ai';
276
+ let selectedStyle = null;
277
+ let isGenerating = false;
278
+
279
+ const styleTemplates = {
280
+ cinema: " cinematic lighting, letterbox aspect, rich color grading",
281
+ realistic: " detailed, raw stock photo style",
282
+ photography: "85mm lens, shallow depth of field, natural film grain",
283
+ fantasy: " epic fantasy, vibrant colors, surreal composition"
284
+ };
285
+
286
+
287
+
288
+
289
+
290
+ function saveSettingsToStorage() {
291
+ const s = {
292
+ model: document.getElementById('model').value,
293
+ width: Number(document.getElementById('width').value || 1024),
294
+ height: Number(document.getElementById('height').value || 1024),
295
+ seed: Number(document.getElementById('seed').value || 42),
296
+ randomSeed: document.getElementById('randomSeed').checked,
297
+ enhance: document.getElementById('enhance').checked
298
+ };
299
+ try { localStorage.setItem('ai_img_settings', JSON.stringify(s)); } catch(e){}
300
+ }
301
+ function loadSettingsFromStorage() {
302
+ try {
303
+ const s = JSON.parse(localStorage.getItem('ai_img_settings') || '{}');
304
+ if (s.model) document.getElementById('model').value = s.model;
305
+ if (s.width) document.getElementById('width').value = s.width;
306
+ if (s.height) document.getElementById('height').value = s.height;
307
+ if (s.seed || s.seed === 0) document.getElementById('seed').value = s.seed;
308
+ document.getElementById('randomSeed').checked = s.randomSeed !== undefined ? s.randomSeed : true;
309
+ document.getElementById('enhance').checked = s.enhance || false;
310
+ } catch(e){}
311
+ }
312
+ loadSettingsFromStorage();
313
+
314
+ const styleModal = document.getElementById('styleModal');
315
+ const settingsModal = document.getElementById('settingsModal');
316
+
317
+ function openModal(modal) {
318
+ modal.style.display = 'flex';
319
+ modal.setAttribute('aria-hidden','false');
320
+ document.body.style.overflow = 'hidden';
321
+ }
322
+ function closeModal(modal) {
323
+ modal.style.display = 'none';
324
+ modal.setAttribute('aria-hidden','true');
325
+ document.body.style.overflow = '';
326
+ }
327
+
328
+ document.getElementById('styleBtn').addEventListener('click', () => openModal(styleModal));
329
+ document.getElementById('closeStyle').addEventListener('click', () => closeModal(styleModal));
330
+
331
+ document.getElementById('settingsBtn').addEventListener('click', () => openModal(settingsModal));
332
+ document.getElementById('closeSettings').addEventListener('click', () => closeModal(settingsModal));
333
+ document.getElementById('saveSettings').addEventListener('click', () => {
334
+ const widthEl = document.getElementById('width');
335
+ const heightEl = document.getElementById('height');
336
+ widthEl.value = Math.max(64, Math.min(2048, Number(widthEl.value) || 1024));
337
+ heightEl.value = Math.max(64, Math.min(2048, Number(heightEl.value) || 1024));
338
+ saveSettingsToStorage();
339
+ closeModal(settingsModal);
340
+ });
341
+
342
+ document.querySelectorAll('.modal-backdrop').forEach(back => back.addEventListener('click', (e) => {
343
+ if (e.target === back) closeModal(back);
344
+ }));
345
+
346
+ window.addEventListener('keydown', (e) => {
347
+ if (e.key === 'Escape') {
348
+ if (styleModal.style.display === 'flex') closeModal(styleModal);
349
+ if (settingsModal.style.display === 'flex') closeModal(settingsModal);
350
+ }
351
+ });
352
+
353
+ document.querySelectorAll('.style-card').forEach(card => {
354
+ card.addEventListener('click', () => {
355
+ document.querySelectorAll('.style-card').forEach(c => c.classList.remove('selected'));
356
+ card.classList.add('selected');
357
+ selectedStyle = card.dataset.name === 'none' ? null : card.dataset.name;
358
+ closeModal(styleModal);
359
+ });
360
+ });
361
+
362
+ const promptEl = document.getElementById('prompt');
363
+ function autoResizeTextarea() {
364
+ promptEl.style.height = 'auto';
365
+ const newH = Math.min(250, promptEl.scrollHeight);
366
+ promptEl.style.height = newH + 'px';
367
+ }
368
+ promptEl.addEventListener('input', autoResizeTextarea);
369
+ setTimeout(autoResizeTextarea, 0);
370
+
371
+ const randomSeedEl = document.getElementById('randomSeed');
372
+ const seedEl = document.getElementById('seed');
373
+ randomSeedEl.addEventListener('change', () => {
374
+ seedEl.disabled = randomSeedEl.checked;
375
+ });
376
+ seedEl.disabled = randomSeedEl.checked;
377
+
378
+ const imagesContainer = document.getElementById('images');
379
+ const generateBtn = document.getElementById('generateBtn');
380
+
381
+ function randomInt(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; }
382
+
383
+ async function generateImage() {
384
+ if (isGenerating) return;
385
+ const rawPrompt = promptEl.value.trim();
386
+ if (!rawPrompt) {
387
+ const temp = document.createElement('div');
388
+ temp.className = 'image-card';
389
+ temp.innerHTML = '<div class="muted">Please enter a prompt</div>';
390
+ imagesContainer.prepend(temp);
391
+ setTimeout(()=> temp.remove(), 1200);
392
+ return;
393
+ }
394
+
395
+ isGenerating = true;
396
+ generateBtn.disabled = true;
397
+
398
+ let sendPrompt = rawPrompt;
399
+ if (selectedStyle && styleTemplates[selectedStyle]) {
400
+ sendPrompt += ' ' + styleTemplates[selectedStyle];
401
+ }
402
+
403
+ const model = encodeURIComponent(document.getElementById('model').value || 'flux');
404
+ const width = Math.max(64, Math.min(2048, Number(document.getElementById('width').value) || 1024));
405
+ const height = Math.max(64, Math.min(2048, Number(document.getElementById('height').value) || 1024));
406
+ const enhance = document.getElementById('enhance').checked;
407
+ const seed = document.getElementById('randomSeed').checked ? randomInt(0, 999999999) : (Number(document.getElementById('seed').value) || 42);
408
+
409
+ const card = document.createElement('div');
410
+ card.className = 'image-card';
411
+ card.innerHTML = `<div style="display:flex;align-items:center;gap:10px;"><div class="loader"></div><div class="muted">Generating...</div></div>`;
412
+ imagesContainer.prepend(card);
413
+
414
+ try {
415
+ const encodedPrompt = encodeURIComponent(sendPrompt);
416
+ const url = `${baseUrl}/prompt/${encodedPrompt}?model=${model}&width=${width}&height=${height}&seed=${seed}&nologo=true&safe=false${enhance ? '&enhance=true' : ''}`;
417
+
418
+ const res = await fetch(url);
419
+ if (!res.ok) throw new Error('Network response not OK: ' + res.status);
420
+ const blob = await res.blob();
421
+ const imgUrl = URL.createObjectURL(blob);
422
+
423
+ card.innerHTML = `<img src="${imgUrl}" alt="generated image">`;
424
+ } catch (err) {
425
+ console.error(err);
426
+ card.innerHTML = `<div class="muted" style="color:#ff6b6b;">Error generating image</div>`;
427
+ } finally {
428
+ isGenerating = false;
429
+ generateBtn.disabled = false;
430
+ }
431
+ }
432
+
433
+ generateBtn.addEventListener('click', generateImage);
434
+
435
+ promptEl.addEventListener('keydown', (e) => {
436
+ if (e.key === 'Enter' && (e.ctrlKey || e.metaKey)) {
437
+ generateImage();
438
+ }
439
+ });
440
+
441
+ window.addEventListener('beforeunload', saveSettingsToStorage);
442
+ </script>
443
+ </body>
444
+ </html>