GitHub Copilot commited on
Commit
2c8d5e7
·
1 Parent(s): 4d8e202

Restore previous swirl animation for image generation loader

Browse files
Files changed (1) hide show
  1. static/index.html +208 -37
static/index.html CHANGED
@@ -424,71 +424,213 @@
424
  }
425
 
426
  .image-container.loading {
427
- min-height: 280px;
428
- min-width: 280px;
429
- background: #000;
430
  display: flex;
431
  align-items: center;
432
  justify-content: center;
433
  position: relative;
434
  overflow: hidden;
 
435
  }
436
 
437
- /* Movie-like Rotating Gradient */
438
- .image-container.loading::before {
439
- content: '';
440
  position: absolute;
441
- inset: -50%;
442
- background: conic-gradient(from 0deg,
443
- transparent 0deg,
444
- #00d4aa 60deg,
445
- #00bcd4 120deg,
446
- #2d8cbe 180deg,
447
- transparent 240deg);
448
- animation: rotate-gradient 4s linear infinite;
449
- opacity: 0.8;
450
- }
451
-
452
- /* Dark overlay to make text readable */
453
- .image-container.loading::after {
454
- content: 'Creating image...';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
455
  position: absolute;
456
- inset: 4px;
457
- background: #1a1a2e;
458
  display: flex;
459
  align-items: center;
460
  justify-content: center;
461
- color: rgba(255, 255, 255, 0.9);
462
- font-size: 14px;
463
- font-weight: 500;
464
- border-radius: 8px;
465
- animation: pulse-text 2s infinite ease-in-out;
 
 
 
 
 
 
 
 
 
 
 
466
  }
467
 
468
- @keyframes rotate-gradient {
469
  0% {
470
- transform: rotate(0deg);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
471
  }
472
 
473
  100% {
474
- transform: rotate(360deg);
 
 
 
475
  }
476
  }
477
 
478
- @keyframes pulse-text {
 
 
 
 
479
 
480
  0%,
481
  100% {
482
- color: rgba(255, 255, 255, 0.7);
483
- transform: scale(0.98);
 
484
  }
485
 
486
  50% {
487
- color: rgba(255, 255, 255, 1);
488
- transform: scale(1);
 
489
  }
490
  }
491
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
492
  .image-actions {
493
  position: absolute;
494
  bottom: 8px;
@@ -1532,18 +1674,47 @@
1532
  const chatContainer = document.getElementById('chatContainer');
1533
  const messagesContainer = document.getElementById('chatMessages');
1534
 
1535
- // Create loading message
1536
  const div = document.createElement('div');
1537
  div.className = 'message assistant';
1538
  div.innerHTML = `
1539
  <div class="message-wrapper">
1540
  <div class="message-content">
1541
  <p>Generating image: "${prompt}"</p>
1542
- <div class="image-container loading"></div>
 
 
 
 
 
 
 
 
1543
  </div>
1544
  </div>
1545
  `;
1546
  messagesContainer.appendChild(div);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1547
  chatContainer.scrollTop = chatContainer.scrollHeight;
1548
 
1549
  // Create Pollinations URL
 
424
  }
425
 
426
  .image-container.loading {
427
+ min-height: 320px;
428
+ min-width: 320px;
429
+ background: #020205;
430
  display: flex;
431
  align-items: center;
432
  justify-content: center;
433
  position: relative;
434
  overflow: hidden;
435
+ border-radius: 12px;
436
  }
437
 
438
+ .image-container.loading .blob {
 
 
439
  position: absolute;
440
+ width: 200%;
441
+ height: 200%;
442
+ border-radius: 50%;
443
+ filter: blur(80px);
444
+ mix-blend-mode: screen;
445
+ opacity: 0.65;
446
+ will-change: transform;
447
+ }
448
+
449
+ .image-container.loading .blob-1 {
450
+ background: radial-gradient(circle at center, #00ffff 0%, transparent 70%);
451
+ top: -50%;
452
+ left: -50%;
453
+ animation: move-cyan 12s infinite alternate ease-in-out;
454
+ }
455
+
456
+ .image-container.loading .blob-2 {
457
+ background: radial-gradient(circle at center, #2b00ff 0%, transparent 70%);
458
+ bottom: -50%;
459
+ right: -50%;
460
+ animation: move-blue 15s infinite alternate ease-in-out;
461
+ }
462
+
463
+ .image-container.loading .blob-3 {
464
+ background: radial-gradient(circle at center, #0066ff 0%, transparent 70%);
465
+ top: 0;
466
+ left: 0;
467
+ animation: move-mid 10s infinite alternate ease-in-out;
468
+ }
469
+
470
+ .image-container.loading .blob-4 {
471
+ background: radial-gradient(circle at center, #00ffd5 0%, transparent 70%);
472
+ bottom: 0;
473
+ left: 0;
474
+ animation: move-teal 15s infinite alternate ease-in-out;
475
+ }
476
+
477
+ @keyframes move-cyan {
478
+ 0% {
479
+ transform: translate3d(0, 0, 0) scale(1) rotate(0deg);
480
+ }
481
+
482
+ 50% {
483
+ transform: translate3d(40%, 25%, 0) scale(1.4) rotate(90deg);
484
+ }
485
+
486
+ 100% {
487
+ transform: translate3d(5%, 10%, 0) scale(1) rotate(-45deg);
488
+ }
489
+ }
490
+
491
+ @keyframes move-blue {
492
+ 0% {
493
+ transform: translate3d(0, 0, 0) scale(1.3) rotate(0deg);
494
+ }
495
+
496
+ 50% {
497
+ transform: translate3d(-50%, -35%, 0) scale(0.9) rotate(-120deg);
498
+ }
499
+
500
+ 100% {
501
+ transform: translate3d(-15%, 20%, 0) scale(1.3) rotate(30deg);
502
+ }
503
+ }
504
+
505
+ @keyframes move-mid {
506
+ 0% {
507
+ transform: translate3d(0, 0, 0) rotate(0deg) scale(1);
508
+ }
509
+
510
+ 50% {
511
+ transform: translate3d(35%, 35%, 0) rotate(180deg) scale(1.5);
512
+ }
513
+
514
+ 100% {
515
+ transform: translate3d(-15%, -25%, 0) rotate(360deg) scale(0.9);
516
+ }
517
+ }
518
+
519
+ @keyframes move-teal {
520
+ 0% {
521
+ transform: translate3d(0, 0, 0) scale(0.9);
522
+ }
523
+
524
+ 50% {
525
+ transform: translate3d(40%, -50%, 0) scale(1.6);
526
+ }
527
+
528
+ 100% {
529
+ transform: translate3d(10%, 10%, 0) scale(0.9);
530
+ }
531
+ }
532
+
533
+ .loading-text-container {
534
  position: absolute;
 
 
535
  display: flex;
536
  align-items: center;
537
  justify-content: center;
538
+ z-index: 10;
539
+ font-size: clamp(14px, 4vw, 18px);
540
+ font-weight: 700;
541
+ text-transform: uppercase;
542
+ letter-spacing: 0.02em;
543
+ }
544
+
545
+ .loading-text-container .char {
546
+ display: inline-block;
547
+ color: white;
548
+ opacity: 0;
549
+ animation: glitchReveal 0.4s steps(2, start) forwards;
550
+ }
551
+
552
+ .loading-text-container .space {
553
+ width: 0.4em;
554
  }
555
 
556
+ @keyframes glitchReveal {
557
  0% {
558
+ opacity: 0;
559
+ transform: translateX(-2px);
560
+ filter: brightness(2);
561
+ }
562
+
563
+ 20% {
564
+ opacity: 0.5;
565
+ transform: translateX(2px);
566
+ }
567
+
568
+ 40% {
569
+ opacity: 0;
570
+ transform: translateX(-1px);
571
+ }
572
+
573
+ 60% {
574
+ opacity: 0.8;
575
+ transform: translateX(1px);
576
+ }
577
+
578
+ 80% {
579
+ opacity: 0.3;
580
+ transform: translateX(-2px);
581
  }
582
 
583
  100% {
584
+ opacity: 1;
585
+ transform: translateX(0);
586
+ filter: brightness(1);
587
+ text-shadow: 0 0 15px #00ffff;
588
  }
589
  }
590
 
591
+ .loading-text-container .char-loop {
592
+ animation: subtleGlow 4s infinite ease-in-out;
593
+ }
594
+
595
+ @keyframes subtleGlow {
596
 
597
  0%,
598
  100% {
599
+ opacity: 1;
600
+ text-shadow: 0 0 15px rgba(0, 255, 255, 0.6);
601
+ transform: scale(1);
602
  }
603
 
604
  50% {
605
+ opacity: 0.7;
606
+ text-shadow: 0 0 5px rgba(0, 255, 255, 0.1);
607
+ transform: scale(0.98);
608
  }
609
  }
610
 
611
+ .image-container.loading .vignette {
612
+ position: absolute;
613
+ top: 0;
614
+ left: 0;
615
+ width: 100%;
616
+ height: 100%;
617
+ background: radial-gradient(circle at center, transparent 10%, rgba(0, 0, 0, 0.5) 100%);
618
+ z-index: 4;
619
+ pointer-events: none;
620
+ }
621
+
622
+ .image-container.loading .noise {
623
+ position: absolute;
624
+ top: 0;
625
+ left: 0;
626
+ width: 100%;
627
+ height: 100%;
628
+ opacity: 0.05;
629
+ pointer-events: none;
630
+ z-index: 5;
631
+ background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 400 400' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.95' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E");
632
+ }
633
+
634
  .image-actions {
635
  position: absolute;
636
  bottom: 8px;
 
1674
  const chatContainer = document.getElementById('chatContainer');
1675
  const messagesContainer = document.getElementById('chatMessages');
1676
 
1677
+ // Create loading message with mesh gradient animation
1678
  const div = document.createElement('div');
1679
  div.className = 'message assistant';
1680
  div.innerHTML = `
1681
  <div class="message-wrapper">
1682
  <div class="message-content">
1683
  <p>Generating image: "${prompt}"</p>
1684
+ <div class="image-container loading">
1685
+ <div class="blob blob-1"></div>
1686
+ <div class="blob blob-2"></div>
1687
+ <div class="blob blob-3"></div>
1688
+ <div class="blob blob-4"></div>
1689
+ <div class="vignette"></div>
1690
+ <div class="noise"></div>
1691
+ <div class="loading-text-container" id="loadingText-${Date.now()}"></div>
1692
+ </div>
1693
  </div>
1694
  </div>
1695
  `;
1696
  messagesContainer.appendChild(div);
1697
+
1698
+ // Animate loading text with glitch entry and glow loop
1699
+ const textContainer = div.querySelector('.loading-text-container');
1700
+ const text = 'CREATING IMAGE';
1701
+ [...text].forEach((char, i) => {
1702
+ const span = document.createElement('span');
1703
+ if (char === ' ') {
1704
+ span.className = 'space';
1705
+ } else {
1706
+ span.className = 'char';
1707
+ span.innerText = char;
1708
+ span.style.setProperty('--i', i);
1709
+ span.style.animationDelay = `${i * 0.05}s`;
1710
+ span.addEventListener('animationend', (e) => {
1711
+ if (e.animationName === 'glitchReveal') {
1712
+ span.classList.add('char-loop');
1713
+ }
1714
+ });
1715
+ }
1716
+ textContainer.appendChild(span);
1717
+ });
1718
  chatContainer.scrollTop = chatContainer.scrollHeight;
1719
 
1720
  // Create Pollinations URL