chore: added audio to murmurations 4278d786
Steve Simkins · 2026-05-03 19:56 1 file(s) · +34 −0
src/pages/murmurations.astro +34 −0
33 33
	>
34 34
		Back
35 35
	</a>
36 +
	<audio id="murmuration-audio" src="/murmuration.mp3" loop preload="none"></audio>
37 +
	<button
38 +
		id="audio-btn"
39 +
		class="fixed right-16 bottom-4 z-10 flex h-10 w-10 items-center justify-center rounded-full border border-textColor/60 bg-bgColor/60 p-0 text-base hover:bg-textColor/15 active:bg-textColor/15"
40 +
		style="bottom: max(1rem, env(safe-area-inset-bottom)); right: calc(max(1rem, env(safe-area-inset-right)) + 3rem);"
41 +
		aria-label="Play audio"
42 +
		aria-pressed="false"
43 +
	>
44 +
		<span id="audio-icon">▶</span>
45 +
	</button>
36 46
	<button
37 47
		id="info-btn"
38 48
		class="fixed right-4 bottom-4 z-10 flex h-10 w-10 items-center justify-center rounded-full border border-textColor/60 bg-bgColor/60 p-0 text-base hover:bg-textColor/15 active:bg-textColor/15"
68 78
			That fixed count is why turning waves cross the flock so fast and stay crisp at any density.
69 79
		</p>
70 80
	</div>
81 +
	<script>
82 +
		const audioBtn = document.getElementById("audio-btn") as HTMLButtonElement | null;
83 +
		const audioEl = document.getElementById("murmuration-audio") as HTMLAudioElement | null;
84 +
		const audioIcon = document.getElementById("audio-icon");
85 +
		if (audioBtn && audioEl && audioIcon) {
86 +
			audioBtn.addEventListener("click", async () => {
87 +
				if (audioEl.paused) {
88 +
					try {
89 +
						await audioEl.play();
90 +
						audioIcon.textContent = "⏸";
91 +
						audioBtn.setAttribute("aria-pressed", "true");
92 +
						audioBtn.setAttribute("aria-label", "Pause audio");
93 +
					} catch (err) {
94 +
						console.error("Audio play failed", err);
95 +
					}
96 +
				} else {
97 +
					audioEl.pause();
98 +
					audioIcon.textContent = "▶";
99 +
					audioBtn.setAttribute("aria-pressed", "false");
100 +
					audioBtn.setAttribute("aria-label", "Play audio");
101 +
				}
102 +
			});
103 +
		}
104 +
	</script>
71 105
	<script>
72 106
		const btn = document.getElementById("info-btn") as HTMLButtonElement | null;
73 107
		const panel = document.getElementById("info-panel") as HTMLDivElement | null;