diff --git a/main-site/easter-egg.js b/main-site/easter-egg.js index f914d4b..4d7722e 100644 --- a/main-site/easter-egg.js +++ b/main-site/easter-egg.js @@ -82,28 +82,14 @@ function launch() { active = true; - - // Inject keyframes once - if (!document.getElementById('bpb-balloon-style')) { - var style = document.createElement('style'); - style.id = 'bpb-balloon-style'; - style.textContent = [ - '@keyframes bpb-float {', - ' 0% { transform: translateX(var(--bx)) translateY(0) rotate(var(--br)); opacity: 0; }', - ' 8% { opacity: 1; }', - ' 85% { opacity: 1; }', - ' 100% { transform: translateX(calc(var(--bx) * -1)) translateY(var(--by)) rotate(calc(var(--br) * -0.5)); opacity: 0; }', - '}', - ].join('\n'); - document.head.appendChild(style); - } + console.log('[🎈 easter egg] building container'); var container = document.createElement('div'); Object.assign(container.style, { position: 'fixed', inset: '0', pointerEvents: 'none', - zIndex: '9', // below Bulma navbar (z-index 30) + zIndex: '9', overflow: 'hidden', }); document.body.insertBefore(container, document.body.firstChild); @@ -111,36 +97,46 @@ var count = 22; for (var i = 0; i < count; i++) { (function (idx) { + var delay = idx * 130 + Math.random() * 150; setTimeout(function () { - var color = COLORS[Math.floor(Math.random() * COLORS.length)]; - var size = 38 + Math.random() * 32; // 38–70 px - var leftPct = 3 + Math.random() * 94; // 3–97 % - var sway = (Math.random() * 40 - 20) + 'px'; // ±20 px horizontal drift - var tilt = (Math.random() * 24 - 12) + 'deg'; - var dur = 4500 + Math.random() * 3500; // 4.5–8 s - var riseAmt = -(window.innerHeight + size * 2); // rise full viewport height + var color = COLORS[Math.floor(Math.random() * COLORS.length)]; + var size = 38 + Math.random() * 32; + var leftPct = 3 + Math.random() * 94; + var sway = Math.random() * 40 - 20; // ±20 px + var tilt = Math.random() * 24 - 12; // ±12 deg + var dur = 4500 + Math.random() * 3500; + var rise = window.innerHeight + size * 2; var wrap = document.createElement('div'); Object.assign(wrap.style, { - position: 'absolute', - bottom: (-size * 1.64 - 10) + 'px', - left: leftPct + '%', - '--bx': sway, - '--by': riseAmt + 'px', - '--br': tilt, - animation: 'bpb-float ' + dur + 'ms cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards', - animationDelay: (idx * 120 + Math.random() * 200) + 'ms', + position: 'absolute', + bottom: (-size * 1.64 - 10) + 'px', + left: leftPct + '%', }); - wrap.appendChild(makeBalloon(color, size)); container.appendChild(wrap); - }, 0); + + // Web Animations API — no CSS custom properties needed + wrap.animate([ + { transform: 'translateX(0px) translateY(0px) rotate(' + tilt + 'deg)', opacity: 0 }, + { transform: 'translateX(0px) translateY(0px) rotate(' + tilt + 'deg)', opacity: 1, offset: 0.06 }, + { transform: 'translateX(' + sway + 'px) translateY(' + (-rise * 0.5) + 'px) rotate(' + (-tilt * 0.3) + 'deg)', opacity: 1, offset: 0.5 }, + { transform: 'translateX(' + (-sway) + 'px) translateY(' + (-rise) + 'px) rotate(' + (-tilt * 0.6) + 'deg)', opacity: 0 }, + ], { + duration: dur, + easing: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)', + fill: 'forwards', + }); + + if (idx === 0) console.log('[🎈 easter egg] first balloon animated, rise=' + rise + 'px dur=' + dur + 'ms'); + }, delay); })(i); } setTimeout(function () { + console.log('[🎈 easter egg] cleaning up'); container.remove(); active = false; - }, 12000); + }, 14000); } })();