Skip to content

Commit 507fd3a

Browse files
committed
more
1 parent 00665c3 commit 507fd3a

File tree

1 file changed

+103
-2
lines changed

1 file changed

+103
-2
lines changed

static/coffee/main/addy.js

+103-2
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ style.textContent = `
4242
.balloon {
4343
position: absolute;
4444
animation: float 15s ease-in-out infinite;
45+
cursor: pointer;
46+
pointer-events: auto;
4547
}
4648
.balloon-string {
4749
width: 1px;
@@ -57,6 +59,7 @@ style.textContent = `
5759
position: relative;
5860
margin: 0 auto;
5961
font-weight: bold;
62+
animation: inflate 0.5s ease-out;
6063
}
6164
.balloon-body::before,
6265
.balloon-body::after {
@@ -105,6 +108,10 @@ style.textContent = `
105108
0% { transform: translateY(0) rotate(0deg); }
106109
100% { transform: translateY(-100vh) rotate(720deg); }
107110
}
111+
@keyframes inflate {
112+
0% { transform: scale(0); }
113+
100% { transform: scale(1); }
114+
}
108115
@media (max-width: 600px) {
109116
.banner-letter {
110117
font-size: 16px;
@@ -164,6 +171,99 @@ function createBalloon() {
164171
balloonBody.style.backgroundColor = `hsl(${hue}, 100%, 70%)`;
165172

166173
effectsContainer.appendChild(balloon);
174+
175+
// Add click event listener to pop the balloon
176+
balloon.addEventListener('click', () => {
177+
popBalloon(balloon);
178+
});
179+
}
180+
181+
// Function to pop a balloon
182+
function popBalloon(balloon) {
183+
// Play pop sound
184+
const popSound = new Audio(`data:audio/mp3;base64,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
229+
GaN65YQUGbsb/paBxEN98OhE1MRCujuutlB8QqYZUFBY8YgmCBZgQ7QyESqolC+icsmlK34dkFh9
230+
dwHFKSmxayaA8RcgFHod1etQOR0MQCpEvKOWi5OljCRe2JJDxEwpODqxdBlhkdCIiqgQmFBIg4pA
231+
sd5sh/w0SLBV/y91EHLanQbDxaaVBFiJaVVZ9bHIzLmAW//7YMTzAA7pKT3smRNh0ZznPYSZ5SAs
232+
OFBITF0EqeAGChllhdJaLJYZas/7BSoE6GQDTIootUJkS7C7pokJFFpyIibThFFdslR3LBVBOhqG
233+
2JiFcjjCl1kcY0Mqu21n6xrLxsj6JkakaDgPHpVf7C87mFGVlh5kbWe1Jo4kVMmVCz8tupMgs19T
234+
yMaRACSAFoUIlZ0M7x+2Q4YGvlTVlDAwaDlMQU1FMy4xMDBVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
235+
VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
236+
VVVVVVVVVVVVVf/7YMT1AA7VQTvssG3p1qRnvaMOXFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
237+
VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
238+
VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
239+
VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
240+
VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVf/7QMT2gNBFSzfspG9g
241+
YodiUPCNHVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
242+
VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
243+
VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV`);
244+
popSound.play();
245+
246+
// Create pop effect
247+
const popEffect = document.createElement('div');
248+
popEffect.style.position = 'absolute';
249+
popEffect.style.left = balloon.style.left;
250+
popEffect.style.top = balloon.style.top;
251+
popEffect.style.width = '60px';
252+
popEffect.style.height = '60px';
253+
popEffect.style.borderRadius = '50%';
254+
popEffect.style.backgroundColor = balloon.querySelector('.balloon-body').style.backgroundColor;
255+
popEffect.style.opacity = '0.7';
256+
popEffect.style.animation = 'pop 0.3s ease-out forwards';
257+
258+
effectsContainer.appendChild(popEffect);
259+
260+
// Remove the balloon
261+
balloon.remove();
262+
263+
// Remove the pop effect after animation
264+
setTimeout(() => {
265+
popEffect.remove();
266+
}, 300);
167267
}
168268

169269
// Function to create a single confetti
@@ -190,11 +290,12 @@ function createConfettiEffect() {
190290
}
191291
}
192292

193-
194293
// Function to stop the effect
195294
function stopEffect() {
196295
effectsContainer.remove();
197296
document.removeEventListener('keydown', escapeKeyHandler);
297+
clearInterval(createConfettiEffect);
298+
clearInterval(createBalloon);
198299
}
199300

200301
// Event listener for Escape key
@@ -208,10 +309,10 @@ function escapeKeyHandler(event) {
208309
export function startBirthday() {
209310
document.addEventListener('keydown', escapeKeyHandler);
210311

211-
212312
createBirthdayBanner();
213313
for (let i = 0; i < 5; i++) {
214314
createBalloon();
215315
}
216316
setInterval(createConfettiEffect, 200);
317+
setInterval(createBalloon, 5000);
217318
}

0 commit comments

Comments
 (0)