my website at ewancroft.uk
6
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: enhance Happy Mac beep sound with ADSR envelope and improve animation scaling

+50 -2
+50 -2
src/lib/components/HappyMacEasterEgg.svelte
··· 12 12 } 13 13 }); 14 14 15 + function playBeep() { 16 + try { 17 + const audioContext = new AudioContext(); 18 + const now = audioContext.currentTime; 19 + 20 + // Tributary recreation of the classic Mac startup chord 21 + // This is NOT the original sound - it's an approximation using Web Audio API 22 + // The original Mac beep was a major chord: F4, A4, C5 23 + // Frequencies: ~349 Hz, ~440 Hz, ~523 Hz 24 + const frequencies = [349, 440, 523]; 25 + const masterGain = audioContext.createGain(); 26 + masterGain.connect(audioContext.destination); 27 + masterGain.gain.value = 0.15; 28 + 29 + // Create three oscillators for the chord 30 + frequencies.forEach((freq) => { 31 + const oscillator = audioContext.createOscillator(); 32 + const gainNode = audioContext.createGain(); 33 + 34 + oscillator.type = 'sine'; // Original Mac used sine waves 35 + oscillator.frequency.value = freq; 36 + 37 + // ADSR envelope for a more authentic sound 38 + gainNode.gain.setValueAtTime(0, now); 39 + gainNode.gain.linearRampToValueAtTime(0.3, now + 0.02); // Attack 40 + gainNode.gain.exponentialRampToValueAtTime(0.01, now + 1.0); // Decay 41 + 42 + oscillator.connect(gainNode); 43 + gainNode.connect(masterGain); 44 + 45 + oscillator.start(now); 46 + oscillator.stop(now + 1.0); 47 + }); 48 + } catch (e) { 49 + // Fail silently if audio context isn't available 50 + console.log('Audio playback not available'); 51 + } 52 + } 53 + 15 54 function startAnimation() { 55 + // Play the beep first 56 + playBeep(); 57 + 16 58 isVisible = true; 17 59 position = -100; 18 60 ··· 109 151 @keyframes hop { 110 152 0%, 111 153 100% { 112 - transform: translateY(0) rotate(0deg); 154 + transform: translateY(0) rotate(0deg) scaleY(1) scaleX(1); 155 + } 156 + 25% { 157 + transform: translateY(-10px) rotate(2deg) scaleY(1.15) scaleX(0.9); 113 158 } 114 159 50% { 115 - transform: translateY(-20px) rotate(5deg); 160 + transform: translateY(-20px) rotate(5deg) scaleY(1) scaleX(1); 161 + } 162 + 75% { 163 + transform: translateY(-10px) rotate(2deg) scaleY(0.85) scaleX(1.1); 116 164 } 117 165 } 118 166