Easter egg: trigger on copyright symbol click only
Previously fired on 5 rapid taps anywhere on the page. Now triggers with a single click on the © in the footer. Added id="bpb-copyright" to the symbol span in nav.js. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
2ebbe4fbe0
commit
c503d6dd75
@ -13,7 +13,6 @@
|
|||||||
body.setAttribute('rx', '21'); body.setAttribute('ry', '25');
|
body.setAttribute('rx', '21'); body.setAttribute('ry', '25');
|
||||||
body.setAttribute('fill', color); body.setAttribute('opacity', '0.88');
|
body.setAttribute('fill', color); body.setAttribute('opacity', '0.88');
|
||||||
|
|
||||||
// shine
|
|
||||||
var shine = document.createElementNS(SVG_NS, 'ellipse');
|
var shine = document.createElementNS(SVG_NS, 'ellipse');
|
||||||
shine.setAttribute('cx', '18'); shine.setAttribute('cy', '16');
|
shine.setAttribute('cx', '18'); shine.setAttribute('cy', '16');
|
||||||
shine.setAttribute('rx', '7'); shine.setAttribute('ry', '5');
|
shine.setAttribute('rx', '7'); shine.setAttribute('ry', '5');
|
||||||
@ -37,52 +36,25 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
var active = false;
|
var active = false;
|
||||||
var tapCount = 0;
|
|
||||||
var tapTimer = null;
|
|
||||||
var lastTouch = 0;
|
|
||||||
|
|
||||||
function registerTap(source, target) {
|
function attach() {
|
||||||
if (active) { console.log('[🎈 easter egg] already active, ignoring'); return; }
|
var el = document.getElementById('bpb-copyright');
|
||||||
tapCount++;
|
if (!el) return;
|
||||||
clearTimeout(tapTimer);
|
el.addEventListener('click', function () {
|
||||||
tapTimer = setTimeout(function () {
|
if (active) return;
|
||||||
console.log('[🎈 easter egg] tap window expired, resetting count');
|
|
||||||
tapCount = 0;
|
|
||||||
}, 3000);
|
|
||||||
console.log('[🎈 easter egg] tap ' + tapCount + '/5 via ' + source + ' on <' + (target.tagName || '?').toLowerCase() + '>');
|
|
||||||
if (tapCount >= 5) {
|
|
||||||
tapCount = 0;
|
|
||||||
console.log('[🎈 easter egg] launching!');
|
|
||||||
launch();
|
launch();
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// touchstart for mobile (fires immediately, not affected by scroll)
|
// Footer is injected by nav.js — wait for it
|
||||||
document.addEventListener('touchstart', function (e) {
|
if (document.readyState === 'loading') {
|
||||||
if (e.target.closest('input, select, textarea')) {
|
document.addEventListener('DOMContentLoaded', attach);
|
||||||
console.log('[🎈 easter egg] touchstart ignored — form element');
|
} else {
|
||||||
return;
|
attach();
|
||||||
}
|
}
|
||||||
lastTouch = Date.now();
|
|
||||||
registerTap('touch', e.target);
|
|
||||||
}, { passive: true });
|
|
||||||
|
|
||||||
// click for desktop (deduplicated from touch events)
|
|
||||||
document.addEventListener('click', function (e) {
|
|
||||||
if (Date.now() - lastTouch < 500) {
|
|
||||||
console.log('[🎈 easter egg] click deduplicated (touch fired recently)');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (e.target.closest('input, select, textarea')) {
|
|
||||||
console.log('[🎈 easter egg] click ignored — form element');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
registerTap('click', e.target);
|
|
||||||
});
|
|
||||||
|
|
||||||
function launch() {
|
function launch() {
|
||||||
active = true;
|
active = true;
|
||||||
console.log('[🎈 easter egg] building container');
|
|
||||||
|
|
||||||
var container = document.createElement('div');
|
var container = document.createElement('div');
|
||||||
Object.assign(container.style, {
|
Object.assign(container.style, {
|
||||||
@ -102,8 +74,8 @@
|
|||||||
var color = COLORS[Math.floor(Math.random() * COLORS.length)];
|
var color = COLORS[Math.floor(Math.random() * COLORS.length)];
|
||||||
var size = 38 + Math.random() * 32;
|
var size = 38 + Math.random() * 32;
|
||||||
var leftPct = 3 + Math.random() * 94;
|
var leftPct = 3 + Math.random() * 94;
|
||||||
var sway = Math.random() * 40 - 20; // ±20 px
|
var sway = Math.random() * 40 - 20;
|
||||||
var tilt = Math.random() * 24 - 12; // ±12 deg
|
var tilt = Math.random() * 24 - 12;
|
||||||
var dur = 4500 + Math.random() * 3500;
|
var dur = 4500 + Math.random() * 3500;
|
||||||
var rise = window.innerHeight + size * 2;
|
var rise = window.innerHeight + size * 2;
|
||||||
|
|
||||||
@ -116,7 +88,6 @@
|
|||||||
wrap.appendChild(makeBalloon(color, size));
|
wrap.appendChild(makeBalloon(color, size));
|
||||||
container.appendChild(wrap);
|
container.appendChild(wrap);
|
||||||
|
|
||||||
// Web Animations API — no CSS custom properties needed
|
|
||||||
wrap.animate([
|
wrap.animate([
|
||||||
{ transform: 'translateX(0px) translateY(0px) rotate(' + tilt + 'deg)', opacity: 0 },
|
{ 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(0px) translateY(0px) rotate(' + tilt + 'deg)', opacity: 1, offset: 0.06 },
|
||||||
@ -127,14 +98,11 @@
|
|||||||
easing: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)',
|
easing: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)',
|
||||||
fill: 'forwards',
|
fill: 'forwards',
|
||||||
});
|
});
|
||||||
|
|
||||||
if (idx === 0) console.log('[🎈 easter egg] first balloon animated, rise=' + rise + 'px dur=' + dur + 'ms');
|
|
||||||
}, delay);
|
}, delay);
|
||||||
})(i);
|
})(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
console.log('[🎈 easter egg] cleaning up');
|
|
||||||
container.remove();
|
container.remove();
|
||||||
active = false;
|
active = false;
|
||||||
}, 14000);
|
}, 14000);
|
||||||
|
|||||||
@ -48,7 +48,7 @@
|
|||||||
' <a target="_blank" rel="noopener noreferrer" href="https://www.instagram.com/beachpartyballoons/"><i class="fa-brands fa-instagram is-size-2"></i></a>\n' +
|
' <a target="_blank" rel="noopener noreferrer" href="https://www.instagram.com/beachpartyballoons/"><i class="fa-brands fa-instagram is-size-2"></i></a>\n' +
|
||||||
' <a target="_blank" rel="noopener noreferrer" href="https://bsky.app/profile/beachpartyballoons.bsky.social"><i class="fa-brands fa-bluesky is-size-2"></i></a>\n' +
|
' <a target="_blank" rel="noopener noreferrer" href="https://bsky.app/profile/beachpartyballoons.bsky.social"><i class="fa-brands fa-bluesky is-size-2"></i></a>\n' +
|
||||||
' </div>\n' +
|
' </div>\n' +
|
||||||
' <p>Copyright © ' + new Date().getFullYear() + ' Beach Party Balloons</p>\n' +
|
' <p>Copyright <span id="bpb-copyright" style="cursor:default;">©</span> ' + new Date().getFullYear() + ' Beach Party Balloons</p>\n' +
|
||||||
' <p>All images & content are property of Beach Party Balloons. Use of images without written permission is prohibited.</p>\n' +
|
' <p>All images & content are property of Beach Party Balloons. Use of images without written permission is prohibited.</p>\n' +
|
||||||
' <p style="font-size:0.8rem;margin-top:0.5rem">\n' +
|
' <p style="font-size:0.8rem;margin-top:0.5rem">\n' +
|
||||||
' <a href="/shop/privacy">Privacy Policy</a>\n' +
|
' <a href="/shop/privacy">Privacy Policy</a>\n' +
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user