Elias207 commited on
Commit
7c3573d
·
verified ·
1 Parent(s): e4ec856

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +114 -24
index.html CHANGED
@@ -231,13 +231,15 @@
231
  justify-content: center;
232
  margin: 0 auto 0.75rem;
233
  }
234
- .ratio-icon > div {
235
  background-color: var(--panel-bg);
236
  border: 2px solid var(--text-tertiary);
237
  border-radius: 6px;
238
  transition: var(--transition-smooth);
 
239
  }
240
- .ratio-option.active .ratio-icon > div {
 
241
  border-color: var(--accent-primary);
242
  background-color: var(--accent-primary-glow);
243
  }
@@ -252,7 +254,10 @@
252
  #icon-portrait > div { width: 28px; height: 50px; }
253
  #icon-landscape > div { width: 60px; height: 34px; }
254
  #icon-square > div { width: 45px; height: 45px; }
255
- #icon-classic > div { width: 55px; height: 41px; }
 
 
 
256
 
257
  #submit-btn {
258
  display: flex; align-items: center; justify-content: center; gap: 0.75rem; width: 100%; padding: 1.1rem;
@@ -288,7 +293,7 @@
288
 
289
  .output-details { display: none !important; }
290
 
291
- .modal-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(18, 24, 38, 0.6); backdrop-filter: blur(10px) saturate(150%); display: none; justify-content: center; align-items: center; z-index: 1000; }
292
  .modal-content {
293
  background: var(--panel-bg);
294
  padding: 2rem 1rem;
@@ -301,7 +306,6 @@
301
  position: relative;
302
  box-shadow: var(--shadow-xl);
303
  border: 1px solid var(--panel-border);
304
- animation: fadeIn 0.3s ease;
305
  }
306
  .modal-header { display: flex; justify-content: center; align-items: center; border-bottom: 1px solid var(--panel-border); padding-bottom: 1rem; margin-bottom: 1.5rem; position: relative; min-height: 50px;}
307
  .modal-header h2 { margin: 0; font-size: 1.8rem; font-weight: 700; color: var(--text-primary); }
@@ -315,12 +319,10 @@
315
  gap: 1rem;
316
  padding: 10px;
317
  }
318
-
319
- /* <<< START: روش جدید و سازگار برای ساخت مربع >>> */
320
  .lora-card {
321
- position: relative; /* ایجاد موقعیت برای عکس داخلی */
322
  height: 0;
323
- padding-bottom: 100%; /* این باعث می‌شود ارتفاع کارت برابر با عرض آن (مربع) شود */
324
  border-radius: var(--radius-input);
325
  overflow: hidden;
326
  cursor: pointer;
@@ -328,9 +330,8 @@
328
  background-color: var(--input-bg);
329
  border: 1px solid transparent;
330
  box-shadow: var(--shadow-sm);
331
- -webkit-user-select: none; /* Safari */
332
- -ms-user-select: none; /* IE 10+ */
333
- user-select: none; /* Standard syntax */
334
  }
335
 
336
  .lora-card:hover {
@@ -340,17 +341,15 @@
340
  }
341
 
342
  .lora-card img {
343
- position: absolute; /* عکس را داخل کادر مربع قرار می‌دهد */
344
  top: 0;
345
  left: 0;
346
  width: 100%;
347
- height: 100%; /* عکس کل فضای مربع را پر می‌کند */
348
  object-fit: cover;
349
  transition: opacity 0.3s ease-in-out;
350
  opacity: 0;
351
  }
352
- /* <<< END: روش جدید و سازگار برای ساخت مربع >>> */
353
-
354
  .lora-card img.loaded {
355
  opacity: 1;
356
  }
@@ -421,6 +420,17 @@
421
  font-weight: 500;
422
  }
423
 
 
 
 
 
 
 
 
 
 
 
 
424
  @media (max-width: 768px) {
425
  main { padding: 1.5rem; } h1 { font-size: 2.2rem; }
426
  .aspect-ratio-selector { grid-template-columns: repeat(2, 1fr); }
@@ -473,9 +483,19 @@
473
  <div class="ratio-icon" id="icon-landscape"><div></div></div>
474
  <div class="ratio-label">افقی ۱۶:۹</div>
475
  </div>
476
- <div class="ratio-option" data-ratio="4:3">
477
- <div class="ratio-icon" id="icon-classic"><div></div></div>
478
- <div class="ratio-label">کلاسیک ۴:۳</div>
 
 
 
 
 
 
 
 
 
 
479
  </div>
480
  <div class="ratio-option active" data-ratio="1:1">
481
  <div class="ratio-icon" id="icon-square"><div></div></div>
@@ -513,6 +533,24 @@
513
  <div id="lora-grid"></div>
514
  </div>
515
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
516
 
517
  <script type="module">
518
  import { Client } from "https://cdn.jsdelivr.net/npm/@gradio/client/dist/index.min.js";
@@ -2247,9 +2285,18 @@
2247
  const originalModalTitleHTML = modalTitle.innerHTML;
2248
  let longPressTimer = null;
2249
  let longPressJustHappened = false;
 
 
 
 
 
 
 
2250
 
2251
  let selectedLora = null;
2252
  let selectedRatio = '1:1';
 
 
2253
  let imageObserver = null;
2254
  let fluxClient = null;
2255
  let countdownInterval = null;
@@ -2501,10 +2548,12 @@
2501
 
2502
  setLoadingState(true, 'در حال پردازش...');
2503
  const getDimensions = (ratio) => {
 
 
 
2504
  switch (ratio) {
2505
- case '9:16': return { width: 720, height: 1280 };
2506
- case '16:9': return { width: 1280, height: 720 };
2507
- case '4:3': return { width: 1152, height: 864 };
2508
  default: return { width: 1024, height: 1024 };
2509
  }
2510
  };
@@ -2621,9 +2670,50 @@
2621
  ratioSelector.addEventListener('click', (event) => {
2622
  const selectedOption = event.target.closest('.ratio-option');
2623
  if (!selectedOption) return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2624
  ratioSelector.querySelectorAll('.ratio-option').forEach(opt => opt.classList.remove('active'));
2625
- selectedOption.classList.add('active');
2626
- selectedRatio = selectedOption.dataset.ratio;
 
 
2627
  });
2628
 
2629
  clearResult();
 
231
  justify-content: center;
232
  margin: 0 auto 0.75rem;
233
  }
234
+ .ratio-icon > div, .ratio-icon > svg {
235
  background-color: var(--panel-bg);
236
  border: 2px solid var(--text-tertiary);
237
  border-radius: 6px;
238
  transition: var(--transition-smooth);
239
+ box-sizing: border-box;
240
  }
241
+ .ratio-option.active .ratio-icon > div,
242
+ .ratio-option.active .ratio-icon > svg {
243
  border-color: var(--accent-primary);
244
  background-color: var(--accent-primary-glow);
245
  }
 
254
  #icon-portrait > div { width: 28px; height: 50px; }
255
  #icon-landscape > div { width: 60px; height: 34px; }
256
  #icon-square > div { width: 45px; height: 45px; }
257
+ #icon-custom > svg { width: 45px; height: 45px; padding: 8px; color: var(--text-tertiary); }
258
+ .ratio-option.active #icon-custom > svg { color: var(--accent-primary); }
259
+ .custom-ratio-value { font-size: 0.75rem; color: var(--text-secondary); margin-top: 2px; height: 1em; }
260
+
261
 
262
  #submit-btn {
263
  display: flex; align-items: center; justify-content: center; gap: 0.75rem; width: 100%; padding: 1.1rem;
 
293
 
294
  .output-details { display: none !important; }
295
 
296
+ .modal-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(18, 24, 38, 0.6); backdrop-filter: blur(10px) saturate(150%); display: none; justify-content: center; align-items: center; z-index: 1000; animation: fadeIn 0.3s ease; }
297
  .modal-content {
298
  background: var(--panel-bg);
299
  padding: 2rem 1rem;
 
306
  position: relative;
307
  box-shadow: var(--shadow-xl);
308
  border: 1px solid var(--panel-border);
 
309
  }
310
  .modal-header { display: flex; justify-content: center; align-items: center; border-bottom: 1px solid var(--panel-border); padding-bottom: 1rem; margin-bottom: 1.5rem; position: relative; min-height: 50px;}
311
  .modal-header h2 { margin: 0; font-size: 1.8rem; font-weight: 700; color: var(--text-primary); }
 
319
  gap: 1rem;
320
  padding: 10px;
321
  }
 
 
322
  .lora-card {
323
+ position: relative;
324
  height: 0;
325
+ padding-bottom: 100%;
326
  border-radius: var(--radius-input);
327
  overflow: hidden;
328
  cursor: pointer;
 
330
  background-color: var(--input-bg);
331
  border: 1px solid transparent;
332
  box-shadow: var(--shadow-sm);
333
+ -webkit-user-select: none;
334
+ user-select: none;
 
335
  }
336
 
337
  .lora-card:hover {
 
341
  }
342
 
343
  .lora-card img {
344
+ position: absolute;
345
  top: 0;
346
  left: 0;
347
  width: 100%;
348
+ height: 100%;
349
  object-fit: cover;
350
  transition: opacity 0.3s ease-in-out;
351
  opacity: 0;
352
  }
 
 
353
  .lora-card img.loaded {
354
  opacity: 1;
355
  }
 
420
  font-weight: 500;
421
  }
422
 
423
+ .modal-content-small { background: var(--panel-bg); padding: 2rem; border-radius: var(--radius-card); max-width: 350px; width: 90%; text-align: center; box-shadow: var(--shadow-xl); position: relative; }
424
+ .modal-content-small h3 { margin-top: 0; margin-bottom: 1.5rem; font-size: 1.5rem; color: var(--text-primary); }
425
+ .modal-content-small .input-group { margin-bottom: 1rem; text-align: right; }
426
+ .modal-content-small label { display: block; margin-bottom: 0.5rem; font-weight: 600; color: var(--text-secondary); font-size: 0.9rem; }
427
+ .modal-content-small input { width: 100%; padding: 0.8rem 1rem; border-radius: var(--radius-input); border: 1px solid var(--input-border); background-color: var(--input-bg); color: var(--text-primary); box-shadow: var(--shadow-sm) inset; font-family: var(--app-font); font-size: 1rem; box-sizing: border-box; transition: var(--transition-smooth); }
428
+ .modal-content-small input:focus { outline: none; border-color: var(--accent-primary); box-shadow: 0 0 0 3px var(--accent-primary-glow), var(--shadow-sm) inset; background-color: var(--panel-bg); }
429
+ #confirm-custom-size-btn { width: 100%; padding: 0.9rem; margin-top: 1rem; font-size: 1rem; font-weight: 700; background-color: var(--accent-primary); color: #fff; border: none; border-radius: var(--radius-btn); cursor: pointer; transition: var(--transition-smooth); }
430
+ #confirm-custom-size-btn:hover { background-color: var(--accent-primary-hover); }
431
+ #close-custom-modal-btn { position: absolute; top: 10px; left: 10px; background: transparent; border: none; font-size: 2rem; cursor: pointer; color: var(--text-tertiary); line-height: 1; padding: 0.5rem; }
432
+
433
+
434
  @media (max-width: 768px) {
435
  main { padding: 1.5rem; } h1 { font-size: 2.2rem; }
436
  .aspect-ratio-selector { grid-template-columns: repeat(2, 1fr); }
 
483
  <div class="ratio-icon" id="icon-landscape"><div></div></div>
484
  <div class="ratio-label">افقی ۱۶:۹</div>
485
  </div>
486
+ <div class="ratio-option" data-ratio="custom">
487
+ <div class="ratio-icon" id="icon-custom">
488
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
489
+ <path d="M21 16V8a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h8"/>
490
+ <circle cx="18" cy="18" r="3"/>
491
+ <path d="M18 15v-2"/><path d="M18 21v-2"/>
492
+ <path d="M15 18h-2"/><path d="M21 18h-2"/>
493
+ </svg>
494
+ </div>
495
+ <div class="ratio-label">
496
+ اندازه دلخواه
497
+ <div class="custom-ratio-value" id="custom-ratio-label-value"></div>
498
+ </div>
499
  </div>
500
  <div class="ratio-option active" data-ratio="1:1">
501
  <div class="ratio-icon" id="icon-square"><div></div></div>
 
533
  <div id="lora-grid"></div>
534
  </div>
535
  </div>
536
+
537
+ <!-- Modal for Custom Size -->
538
+ <div class="modal-overlay" id="custom-size-modal">
539
+ <div class="modal-content-small">
540
+ <button id="close-custom-modal-btn">&times;</button>
541
+ <h3>تنظیم اندازه دلخواه</h3>
542
+ <div class="input-group">
543
+ <label for="custom-width-input">عرض (Width)</label>
544
+ <input type="number" id="custom-width-input" value="1024" min="512" max="1536" step="8" placeholder="بین ۵۱۲ تا ۱۵۳۶">
545
+ </div>
546
+ <div class="input-group">
547
+ <label for="custom-height-input">طول (Height)</label>
548
+ <input type="number" id="custom-height-input" value="1024" min="512" max="1536" step="8" placeholder="بین ۵۱۲ تا ۱۵۳۶">
549
+ </div>
550
+ <button id="confirm-custom-size-btn">تایید و اعمال</button>
551
+ </div>
552
+ </div>
553
+
554
 
555
  <script type="module">
556
  import { Client } from "https://cdn.jsdelivr.net/npm/@gradio/client/dist/index.min.js";
 
2285
  const originalModalTitleHTML = modalTitle.innerHTML;
2286
  let longPressTimer = null;
2287
  let longPressJustHappened = false;
2288
+
2289
+ const customSizeModal = document.getElementById('custom-size-modal');
2290
+ const closeCustomModalBtn = document.getElementById('close-custom-modal-btn');
2291
+ const confirmCustomSizeBtn = document.getElementById('confirm-custom-size-btn');
2292
+ const customWidthInput = document.getElementById('custom-width-input');
2293
+ const customHeightInput = document.getElementById('custom-height-input');
2294
+ const customRatioLabel = document.getElementById('custom-ratio-label-value');
2295
 
2296
  let selectedLora = null;
2297
  let selectedRatio = '1:1';
2298
+ let customWidth = 1024;
2299
+ let customHeight = 1024;
2300
  let imageObserver = null;
2301
  let fluxClient = null;
2302
  let countdownInterval = null;
 
2548
 
2549
  setLoadingState(true, 'در حال پردازش...');
2550
  const getDimensions = (ratio) => {
2551
+ if (ratio === 'custom') {
2552
+ return { width: customWidth, height: customHeight };
2553
+ }
2554
  switch (ratio) {
2555
+ case '9:16': return { width: 768, height: 1344 };
2556
+ case '16:9': return { width: 1344, height: 768 };
 
2557
  default: return { width: 1024, height: 1024 };
2558
  }
2559
  };
 
2670
  ratioSelector.addEventListener('click', (event) => {
2671
  const selectedOption = event.target.closest('.ratio-option');
2672
  if (!selectedOption) return;
2673
+ const ratioValue = selectedOption.dataset.ratio;
2674
+
2675
+ if (ratioValue === 'custom') {
2676
+ customSizeModal.style.display = 'flex';
2677
+ } else {
2678
+ ratioSelector.querySelectorAll('.ratio-option').forEach(opt => opt.classList.remove('active'));
2679
+ selectedOption.classList.add('active');
2680
+ selectedRatio = ratioValue;
2681
+ }
2682
+ });
2683
+
2684
+ closeCustomModalBtn.addEventListener('click', () => {
2685
+ customSizeModal.style.display = 'none';
2686
+ });
2687
+
2688
+ customSizeModal.addEventListener('click', (event) => {
2689
+ if (event.target === customSizeModal) {
2690
+ customSizeModal.style.display = 'none';
2691
+ }
2692
+ });
2693
+
2694
+ confirmCustomSizeBtn.addEventListener('click', () => {
2695
+ const width = parseInt(customWidthInput.value, 10);
2696
+ const height = parseInt(customHeightInput.value, 10);
2697
+
2698
+ if (isNaN(width) || isNaN(height) || width < 512 || height < 512 || width > 1536 || height > 1536) {
2699
+ alert('مقادیر عرض و طول باید بین ۵۱۲ و ۱۵۳۶ پیکسل باشند.');
2700
+ return;
2701
+ }
2702
+
2703
+ if (width % 8 !== 0 || height % 8 !== 0) {
2704
+ alert('مقادیر عرض و طول باید بر ۸ بخش‌پذیر باشند.');
2705
+ return;
2706
+ }
2707
+
2708
+ customWidth = width;
2709
+ customHeight = height;
2710
+ selectedRatio = 'custom';
2711
+
2712
  ratioSelector.querySelectorAll('.ratio-option').forEach(opt => opt.classList.remove('active'));
2713
+ document.querySelector('.ratio-option[data-ratio="custom"]').classList.add('active');
2714
+
2715
+ customRatioLabel.textContent = `${width} x ${height}`;
2716
+ customSizeModal.style.display = 'none';
2717
  });
2718
 
2719
  clearResult();