fix hero anim.

This commit is contained in:
Arlind Ukshini 2026-04-23 13:40:26 +02:00
parent 8bd0fda910
commit ecf83137c9
2 changed files with 19 additions and 43 deletions

View file

@ -71,6 +71,11 @@
el.style.opacity = '1';
el.style.transform = 'none';
});
// The hero-wrap is hidden by CSS (`.js .hero-wrap { opacity: 0 }`)
// to prevent a flash during page activation — unhide it here since
// we're skipping the fade-in tween.
const heroWrap = document.querySelector('.hero-wrap');
if (heroWrap) heroWrap.style.opacity = '1';
// Still fade the Europe map fully in — it's the scene background.
const mapEl = document.getElementById('overview-globe');
if (mapEl) mapEl.style.opacity = '1';
@ -360,50 +365,17 @@
// Script 1 body — HERO + SCENE 2 (architecture stack) + SCENE 3 (words) + SCENE 4 (bifrost arc)
/* -------------------------------------------------------------
HERO staggered intro on load
HERO single overall fade-in. The wrap is hidden via CSS
(`.js .hero-wrap { opacity: 0 }`) so the hero stays invisible
during the page-activation transition, then fades in once
Bifrost has booted.
------------------------------------------------------------- */
const heroTl = gsap.timeline({ defaults: { ease: 'power3.out' } });
// Split the hero title into lines-ish spans for a nicer reveal
const heroTitle = document.querySelector('.hero-title');
if (heroTitle) {
// preserve <br>, wrap visible text chunks in spans
const walk = (node) => {
const kids = [...node.childNodes];
kids.forEach(k => {
if (k.nodeType === Node.TEXT_NODE && k.textContent.trim()) {
const frag = document.createDocumentFragment();
k.textContent.split(/(\s+)/).forEach(tok => {
if (tok.trim()) {
const w = document.createElement('span');
w.className = 'htw';
w.style.display = 'inline-block';
w.style.overflow = 'hidden';
const inner = document.createElement('span');
inner.style.display = 'inline-block';
inner.style.transform = 'translateY(110%)';
inner.style.willChange = 'transform';
inner.textContent = tok;
w.appendChild(inner);
frag.appendChild(w);
} else {
frag.appendChild(document.createTextNode(tok));
}
});
node.replaceChild(frag, k);
} else if (k.nodeType === Node.ELEMENT_NODE && k.tagName !== 'BR') {
walk(k);
}
});
};
walk(heroTitle);
}
heroTl
.from('.eyebrow', { opacity: 0, y: 14, duration: 0.7 }, 0.15)
.to('.hero-title .htw > span', { y: '0%', duration: 1.05, stagger: 0.045, ease: 'power4.out' }, 0.2)
.from('.hero-lede', { opacity: 0, y: 20, duration: 0.9 }, 0.7)
.from('.hero-foot', { opacity: 0, y: 14, duration: 0.8 }, 0.9);
gsap.to('.hero-wrap', {
opacity: 1,
duration: 1.0,
ease: 'power2.out',
delay: 0.1,
});
/* -------------------------------------------------------------
ARCHITECTURE two-phase scrubbed sequence

View file

@ -790,6 +790,10 @@ html {
margin-inline: auto;
padding-top: clamp(2rem, 6vh, 4rem);
}
/* Hide the hero on first paint while JS is booting so it doesn't
flash in raw form during the page-activation transition. The
Bifrost init fades it in once ScrollTriggers are wired up. */
.js .hero-wrap { opacity: 0; }
.eyebrow {
font-size: var(--step-sm);