Add balloon easter egg — long press logo to trigger
Hold the logo for 0.6s (works on mobile touch and desktop mouse) to launch 22 balloon silhouettes floating up from the bottom. Balloons drift with a slight sway, have a shine highlight, and naturally disappear under the navbar. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
5900ce817e
commit
2002d7f35a
@ -111,6 +111,7 @@ Our expertise lies in crafting memorable experiences through a diverse array of
|
||||
|
||||
<div id="site-footer"></div>
|
||||
<script defer src="../script.js"></script>
|
||||
<script src="../easter-egg.js"></script>
|
||||
<!-- <script defer data-domain="beachpartyballoons.com" src="https://metrics.beachpartyballoons.com/js/script.js"></script> -->
|
||||
<script async data-nf='{"formurl":"https://forms.beachpartyballoons.com/forms/contact-us-vjz40v","emoji":"💬","position":"left","bgcolor":"#0dc9ba","width":"500"}' src='https://forms.beachpartyballoons.com/widgets/embed-min.js'></script>
|
||||
|
||||
|
||||
@ -104,6 +104,7 @@
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
||||
<script src="script.js"></script>
|
||||
<script src="easter-egg.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -132,6 +132,7 @@
|
||||
|
||||
<div id="site-footer"></div>
|
||||
<script src="../script.js"></script>
|
||||
<script src="../easter-egg.js"></script>
|
||||
<script src="../contact-form.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
128
main-site/easter-egg.js
Normal file
128
main-site/easter-egg.js
Normal file
@ -0,0 +1,128 @@
|
||||
(function () {
|
||||
var COLORS = ['#11b3be','#ff6b9d','#ffd93d','#6bcb77','#4d96ff','#ff6b35','#c77dff','#ff9f43','#54a0ff','#ff6348'];
|
||||
|
||||
var SVG_NS = 'http://www.w3.org/2000/svg';
|
||||
function makeBalloon(color, size) {
|
||||
var svg = document.createElementNS(SVG_NS, 'svg');
|
||||
svg.setAttribute('viewBox', '0 0 50 82');
|
||||
svg.setAttribute('width', size);
|
||||
svg.setAttribute('height', Math.round(size * 1.64));
|
||||
|
||||
var body = document.createElementNS(SVG_NS, 'ellipse');
|
||||
body.setAttribute('cx', '25'); body.setAttribute('cy', '26');
|
||||
body.setAttribute('rx', '21'); body.setAttribute('ry', '25');
|
||||
body.setAttribute('fill', color); body.setAttribute('opacity', '0.88');
|
||||
|
||||
// shine
|
||||
var shine = document.createElementNS(SVG_NS, 'ellipse');
|
||||
shine.setAttribute('cx', '18'); shine.setAttribute('cy', '16');
|
||||
shine.setAttribute('rx', '7'); shine.setAttribute('ry', '5');
|
||||
shine.setAttribute('fill', 'white'); shine.setAttribute('opacity', '0.25');
|
||||
shine.setAttribute('transform', 'rotate(-20 18 16)');
|
||||
|
||||
var knot = document.createElementNS(SVG_NS, 'path');
|
||||
knot.setAttribute('d', 'M25 51 Q27.5 55.5 25 58.5 Q22.5 55.5 25 51Z');
|
||||
knot.setAttribute('fill', color); knot.setAttribute('opacity', '0.88');
|
||||
|
||||
var str = document.createElementNS(SVG_NS, 'path');
|
||||
str.setAttribute('d', 'M25 58.5 Q20 68 25 80');
|
||||
str.setAttribute('stroke', '#999'); str.setAttribute('stroke-width', '1.2');
|
||||
str.setAttribute('fill', 'none'); str.setAttribute('opacity', '0.7');
|
||||
|
||||
svg.appendChild(body);
|
||||
svg.appendChild(shine);
|
||||
svg.appendChild(knot);
|
||||
svg.appendChild(str);
|
||||
return svg;
|
||||
}
|
||||
|
||||
var active = false;
|
||||
var pressTimer = null;
|
||||
|
||||
function startPress() {
|
||||
pressTimer = setTimeout(function () {
|
||||
if (!active) launch();
|
||||
}, 600);
|
||||
}
|
||||
|
||||
function cancelPress() {
|
||||
clearTimeout(pressTimer);
|
||||
}
|
||||
|
||||
// Long-press on the navbar brand (logo area)
|
||||
document.addEventListener('mousedown', function (e) {
|
||||
if (e.target.closest('.navbar-brand')) startPress();
|
||||
});
|
||||
document.addEventListener('mouseup', cancelPress);
|
||||
document.addEventListener('mouseleave', cancelPress);
|
||||
|
||||
document.addEventListener('touchstart', function (e) {
|
||||
if (e.target.closest('.navbar-brand')) startPress();
|
||||
}, { passive: true });
|
||||
document.addEventListener('touchend', cancelPress);
|
||||
document.addEventListener('touchmove', cancelPress);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
var container = document.createElement('div');
|
||||
Object.assign(container.style, {
|
||||
position: 'fixed',
|
||||
inset: '0',
|
||||
pointerEvents: 'none',
|
||||
zIndex: '9', // below Bulma navbar (z-index 30)
|
||||
overflow: 'hidden',
|
||||
});
|
||||
document.body.insertBefore(container, document.body.firstChild);
|
||||
|
||||
var count = 22;
|
||||
for (var i = 0; i < count; i++) {
|
||||
(function (idx) {
|
||||
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 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);
|
||||
})(i);
|
||||
}
|
||||
|
||||
setTimeout(function () {
|
||||
container.remove();
|
||||
active = false;
|
||||
}, 12000);
|
||||
}
|
||||
})();
|
||||
@ -232,6 +232,7 @@
|
||||
</div>
|
||||
<div id="site-footer"></div>
|
||||
<script src="../script.js"></script>
|
||||
<script src="../easter-egg.js"></script>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const tabs = document.querySelectorAll('.faq-tabs li');
|
||||
|
||||
@ -107,6 +107,7 @@
|
||||
window.GALLERY_API_URL = 'https://photobackend.beachpartyballoons.com';
|
||||
</script>
|
||||
<script src="../script.js" defer></script>
|
||||
<script src="../easter-egg.js"></script>
|
||||
<script src="../update.js" defer></script>
|
||||
<script src="gallery.js" defer></script>
|
||||
</body>
|
||||
|
||||
@ -244,6 +244,7 @@
|
||||
|
||||
<div id="site-footer"></div>
|
||||
<script src="script.js"></script>
|
||||
<script src="easter-egg.js"></script>
|
||||
<script src="update.js"></script>
|
||||
<script src="reviews-data.js"></script>
|
||||
<script src="reviews.js?v=6"></script>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user