Public Access
Carousel hero bg: old image slides out right, new slides in from right
- ::after is now a dark overlay only (no bg image) - .hero-bg container created on first swap - Old slide (Amsterdam default) starts at translateX(0), animates to translateX(100%) — slides out to the right - New slide (winning city) starts at translateX(100%), animates to translateX(0) — slides in from the right - Both fire simultaneously via requestAnimationFrame, same easing - Old slide removed after 1.2s cleanup timeout - Label 'Our <City> server fits your location' slides in from right alongside the carousel animation
This commit is contained in:
@@ -523,26 +523,44 @@ var si = 0,
|
|||||||
c.el.classList.add('server-best');
|
c.el.classList.add('server-best');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
/* Preload city image and animate reveal */
|
/* Preload city image and carousel-slide */
|
||||||
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]) {
|
||||||
var img = new Image();
|
var img = new Image();
|
||||||
img.onload = function() {
|
img.onload = function() {
|
||||||
/* Reveal overlay — slides left-to-right via clip-path */
|
/* Create background container on first swap */
|
||||||
var reveal = document.createElement('div');
|
var bg = hero.querySelector('.hero-bg');
|
||||||
reveal.className = 'hero-city-reveal';
|
if (!bg) {
|
||||||
reveal.style.backgroundImage = "url('" + heroImages[best.host] + "')";
|
bg = document.createElement('div');
|
||||||
hero.appendChild(reveal);
|
bg.className = 'hero-bg';
|
||||||
/* Label — slides right-to-left simultaneously */
|
hero.insertBefore(bg, hero.firstChild);
|
||||||
|
}
|
||||||
|
/* Old slide — starts at current position, slides out right */
|
||||||
|
var oldEl = document.createElement('div');
|
||||||
|
oldEl.className = 'hero-bg-slide old';
|
||||||
|
oldEl.style.backgroundImage = "url('images/city-amsterdam.jpg')";
|
||||||
|
bg.appendChild(oldEl);
|
||||||
|
/* New slide — starts off-screen right, slides in */
|
||||||
|
var newEl = document.createElement('div');
|
||||||
|
newEl.className = 'hero-bg-slide new';
|
||||||
|
newEl.style.backgroundImage = "url('" + heroImages[best.host] + "')";
|
||||||
|
bg.appendChild(newEl);
|
||||||
|
/* Fire both animations together */
|
||||||
|
requestAnimationFrame(function() {
|
||||||
|
oldEl.classList.add('out');
|
||||||
|
newEl.classList.add('in');
|
||||||
|
});
|
||||||
|
/* 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() {
|
requestAnimationFrame(function() {
|
||||||
reveal.classList.add('open');
|
|
||||||
label.classList.add('visible');
|
label.classList.add('visible');
|
||||||
});
|
});
|
||||||
|
/* Clean up old slide after animation done */
|
||||||
|
setTimeout(function() { oldEl.remove(); }, 1200);
|
||||||
};
|
};
|
||||||
img.src = heroImages[best.host];
|
img.src = heroImages[best.host];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,10 +112,37 @@ img { max-width: 100%; height: auto; vertical-align: middle; }
|
|||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
background: var(--hero-bg, url('images/city-amsterdam.jpg')) center/cover no-repeat;
|
background: var(--midnight);
|
||||||
opacity: 0.12;
|
opacity: 0.6;
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
transition: background-image 0.8s cubic-bezier(0.16, 1, 0.3, 1);
|
}
|
||||||
|
.hero-bg {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
z-index: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.hero-bg-slide {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
opacity: 0.12;
|
||||||
|
transition: transform 1s cubic-bezier(0.16, 1, 0.3, 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 {
|
||||||
@@ -377,21 +404,6 @@ 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 {
|
.hero-city-label {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 2rem;
|
bottom: 2rem;
|
||||||
|
|||||||
Reference in New Issue
Block a user