Fix balloon animation: use Web Animations API instead of CSS custom properties in keyframes

This commit is contained in:
chris 2026-06-06 21:38:40 -04:00
parent 75b20e6ca2
commit d026bc8217

View File

@ -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; // 3870 px
var leftPct = 3 + Math.random() * 94; // 397 %
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.58 s
var riseAmt = -(window.innerHeight + size * 2); // rise full viewport height
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',
});
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);
}
})();