Hero: preload city image, left-to-right clip-path reveal, label slide-in

- Preloads the best server's city image via new Image() before showing
- Reveal overlay uses clip-path: inset(0 100% ...) → inset(0) for smooth
  left-to-right slide over the default Amsterdam background
- Label 'Our <City> server fits your location' slides in from right
  simultaneously with backdrop-blur and brass border
- Both animations start and end together via requestAnimationFrame
This commit is contained in:
2026-08-19 22:10:01 +00:00
parent fb8c1b7dea
commit d29dd1174f
2 changed files with 68 additions and 3 deletions
+21 -3
View File
@@ -523,10 +523,28 @@ var si = 0,
c.el.classList.add('server-best'); c.el.classList.add('server-best');
} }
}); });
/* Swap hero background to best server's city */ /* Preload city image and animate reveal */
var hero = document.querySelector('.hero'); var hero = document.querySelector('.hero');
if (hero && heroImages[best.host]) { var bestCard = cards.filter(function(c) { return c.server.host === best.host; })[0];
hero.style.setProperty('--hero-bg', "url('" + heroImages[best.host] + "')"); if (hero && bestCard && heroImages[best.host]) {
var img = new Image();
img.onload = function() {
/* Reveal overlay — slides left-to-right via clip-path */
var reveal = document.createElement('div');
reveal.className = 'hero-city-reveal';
reveal.style.backgroundImage = "url('" + heroImages[best.host] + "')";
hero.appendChild(reveal);
/* Label — slides right-to-left simultaneously */
var label = document.createElement('div');
label.className = 'hero-city-label';
label.innerHTML = 'Our <strong>' + bestCard.server.city + '</strong> server fits your location';
hero.appendChild(label);
requestAnimationFrame(function() {
reveal.classList.add('open');
label.classList.add('visible');
});
};
img.src = heroImages[best.host];
} }
/* Update banner status */ /* Update banner status */
bannerStatus.innerHTML = bannerStatus.innerHTML =
+47
View File
@@ -377,11 +377,58 @@ img { max-width: 100%; height: auto; vertical-align: middle; }
} }
} }
.hero-city-reveal {
position: absolute;
inset: 0;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
opacity: 0.12;
z-index: 0;
clip-path: inset(0 100% 0 0);
will-change: clip-path;
pointer-events: none;
}
.hero-city-reveal.open {
clip-path: inset(0 0 0 0);
}
.hero-city-label {
position: absolute;
bottom: 2rem;
right: 2rem;
background: rgba(13,27,46,0.88);
border: 1px solid var(--line-brass);
border-radius: var(--radius);
padding: 0.7rem 1.25rem;
color: rgba(255,255,255,0.8);
font-family: Marcellus, Georgia, serif;
font-size: 0.9rem;
z-index: 2;
transform: translateX(150%);
transition: transform 0.85s cubic-bezier(0.16, 1, 0.3, 1);
white-space: nowrap;
backdrop-filter: blur(6px);
pointer-events: none;
}
.hero-city-label.visible {
transform: translateX(0);
}
.hero-city-label strong {
color: var(--brass-bright);
font-weight: 400;
}
@media (max-width: 768px) { @media (max-width: 768px) {
.hero { min-height: auto; padding: 3rem 0 0; } .hero { min-height: auto; padding: 3rem 0 0; }
.hero-actions { flex-direction: column; } .hero-actions { flex-direction: column; }
.hero-actions .btn { width: 100%; text-align: center; } .hero-actions .btn { width: 100%; text-align: center; }
.hero-stats { gap: 0.75rem; } .hero-stats { gap: 0.75rem; }
.hero-city-label {
bottom: 1rem;
right: 1rem;
font-size: 0.78rem;
padding: 0.5rem 0.9rem;
}
} }
/* ---- Trust Bar ---- */ /* ---- Trust Bar ---- */