GSAP for all animations, 3x slower, brighter city images

- Added GSAP 3.12.5 from CDN
- Card stagger entrance now uses gsap.fromTo with 0.6s duration, 0.09 stagger
- Carousel slide uses gsap.timeline: old slides out right (3s), new slides
  in from right (3s), label slides in (2.5s after 0.3s offset)
- All animations use power2.out easing
- Image brightness: opacity 0.12→0.25, filter brightness(1.15) saturate(1.1)
- ::after overlay changed from solid midnight @ 0.6 to gradient
  (midnight→transparent @ 0.5) — brighter image with smooth falloff
This commit is contained in:
2026-08-19 22:23:28 +00:00
parent e2e37e18b4
commit 5e315cee0e
3 changed files with 22 additions and 37 deletions
+1
View File
@@ -30,6 +30,7 @@
<link rel="preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" /> <link rel="preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Marcellus&display=swap" media="print" onload="this.media='all'" /> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Marcellus&display=swap" media="print" onload="this.media='all'" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" media="print" onload="this.media='all'" /> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" media="print" onload="this.media='all'" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/gsap.min.js"></script>
<link rel="stylesheet" href="style.css" /> <link rel="stylesheet" href="style.css" />
</head> </head>
<body> <body>
+17 -16
View File
@@ -461,12 +461,11 @@ var si = 0,
cards.push({ el: card, server: s, idx: idx }); cards.push({ el: card, server: s, idx: idx });
}); });
/* Stagger the card entrance animation */ /* GSAP stagger entrance for cards */
cards.forEach(function(c, i) { gsap.fromTo('.server-card',
setTimeout(function() { { opacity: 0, y: 20 },
c.el.classList.add('visible'); { opacity: 1, y: 0, duration: 0.6, stagger: 0.09, ease: 'power2.out' }
}, 80 + i * 70); );
});
function pingServer(host) { function pingServer(host) {
return new Promise(function(resolve) { return new Promise(function(resolve) {
@@ -523,7 +522,7 @@ var si = 0,
c.el.classList.add('server-best'); c.el.classList.add('server-best');
} }
}); });
/* Preload city image and carousel-slide */ /* Preload city image and carousel-slide with GSAP */
var hero = document.querySelector('.hero'); var hero = document.querySelector('.hero');
var bestCard = cards.filter(function(c) { return c.server.host === best.host; })[0]; var bestCard = cards.filter(function(c) { return c.server.host === best.host; })[0];
if (hero && bestCard && heroImages[best.host]) { if (hero && bestCard && heroImages[best.host]) {
@@ -546,21 +545,23 @@ var si = 0,
newEl.className = 'hero-bg-slide new'; newEl.className = 'hero-bg-slide new';
newEl.style.backgroundImage = "url('" + heroImages[best.host] + "')"; newEl.style.backgroundImage = "url('" + heroImages[best.host] + "')";
bg.appendChild(newEl); bg.appendChild(newEl);
/* Fire both animations together */
requestAnimationFrame(function() {
oldEl.classList.add('out');
newEl.classList.add('in');
});
/* Label slides in from right */ /* Label slides in from right */
var label = document.createElement('div'); var label = document.createElement('div');
label.className = 'hero-city-label'; label.className = 'hero-city-label';
label.innerHTML = 'Our <strong>' + bestCard.server.city + '</strong> server fits your location'; label.innerHTML = 'Our <strong>' + bestCard.server.city + '</strong> server fits your location';
hero.appendChild(label); hero.appendChild(label);
requestAnimationFrame(function() {
label.classList.add('visible'); /* GSAP timeline — 3x slower */
gsap.set(oldEl, { x: '0%' });
gsap.set(newEl, { x: '100%' });
gsap.set(label, { x: '150%' });
var tl = gsap.timeline({
onComplete: function() { oldEl.remove(); }
}); });
/* Clean up old slide after animation done */ tl.to(oldEl, { x: '100%', duration: 3, ease: 'power2.out' }, 0)
setTimeout(function() { oldEl.remove(); }, 1200); .to(newEl, { x: '0%', duration: 3, ease: 'power2.out' }, 0)
.to(label, { x: '0%', duration: 2.5, ease: 'power2.out' }, 0.3);
}; };
img.src = heroImages[best.host]; img.src = heroImages[best.host];
} }
+4 -21
View File
@@ -112,8 +112,8 @@ img { max-width: 100%; height: auto; vertical-align: middle; }
content: ''; content: '';
position: absolute; position: absolute;
inset: 0; inset: 0;
background: var(--midnight); background: linear-gradient(135deg, var(--midnight) 50%, rgba(13,27,46,0.4) 100%);
opacity: 0.6; opacity: 0.5;
z-index: 0; z-index: 0;
} }
.hero-bg { .hero-bg {
@@ -128,21 +128,8 @@ img { max-width: 100%; height: auto; vertical-align: middle; }
background-size: cover; background-size: cover;
background-position: center; background-position: center;
background-repeat: no-repeat; background-repeat: no-repeat;
opacity: 0.12; opacity: 0.25;
transition: transform 1s cubic-bezier(0.16, 1, 0.3, 1); filter: brightness(1.15) saturate(1.1);
will-change: transform;
}
.hero-bg-slide.old {
transform: translateX(0);
}
.hero-bg-slide.old.out {
transform: translateX(100%);
}
.hero-bg-slide.new {
transform: translateX(100%);
}
.hero-bg-slide.new.in {
transform: translateX(0);
} }
.hero .container { position: relative; z-index: 1; flex: 1; display: flex; flex-direction: column; justify-content: center; } .hero .container { position: relative; z-index: 1; flex: 1; display: flex; flex-direction: column; justify-content: center; }
.hero-kicker { .hero-kicker {
@@ -417,14 +404,10 @@ img { max-width: 100%; height: auto; vertical-align: middle; }
font-size: 0.9rem; font-size: 0.9rem;
z-index: 2; z-index: 2;
transform: translateX(150%); transform: translateX(150%);
transition: transform 0.85s cubic-bezier(0.16, 1, 0.3, 1);
white-space: nowrap; white-space: nowrap;
backdrop-filter: blur(6px); backdrop-filter: blur(6px);
pointer-events: none; pointer-events: none;
} }
.hero-city-label.visible {
transform: translateX(0);
}
.hero-city-label strong { .hero-city-label strong {
color: var(--brass-bright); color: var(--brass-bright);
font-weight: 400; font-weight: 400;