2024-07-20 21:18:41 +01:00
|
|
|
const playBtn = document.getElementById("play-btn");
|
2024-07-21 00:31:02 +01:00
|
|
|
const catImg = document.getElementsByClassName("cat")[0];
|
2024-07-21 21:39:29 +01:00
|
|
|
const volumeSlider = document.getElementById("volume-slider");
|
|
|
|
const currentVolumeLabel = document.getElementById("current-volume-label");
|
2024-07-21 19:06:07 +01:00
|
|
|
const clickAudio = new Audio("/audio/click.wav");
|
|
|
|
const clickReleaseAudio = new Audio("/audio/click-release.wav");
|
2024-07-20 21:18:41 +01:00
|
|
|
|
2024-07-20 22:16:16 +01:00
|
|
|
const CROSSFADE_DURATION_MS = 5000;
|
|
|
|
const CROSSFADE_INTERVAL_MS = 20;
|
|
|
|
const AUDIO_DURATION_MS = 60000;
|
|
|
|
|
2024-07-20 21:18:41 +01:00
|
|
|
let isPlaying = false;
|
2024-07-21 21:39:29 +01:00
|
|
|
let isFading = false;
|
2024-07-20 21:18:41 +01:00
|
|
|
let currentAudio;
|
2024-07-21 21:39:29 +01:00
|
|
|
let maxVolume = 100;
|
|
|
|
let currentVolume = 0;
|
2024-07-20 21:18:41 +01:00
|
|
|
|
|
|
|
function playAudio() {
|
2024-07-20 21:48:43 +01:00
|
|
|
// add a random query parameter at the end to prevent browser caching
|
|
|
|
currentAudio = new Audio(`/current.mp3?t=${Date.now()}`);
|
2024-07-20 21:18:41 +01:00
|
|
|
currentAudio.onplay = () => {
|
|
|
|
isPlaying = true;
|
|
|
|
playBtn.innerText = "pause";
|
|
|
|
};
|
|
|
|
currentAudio.onpause = () => {
|
|
|
|
isPlaying = false;
|
2024-07-21 21:39:29 +01:00
|
|
|
currentVolume = 0;
|
2024-07-20 21:18:41 +01:00
|
|
|
playBtn.innerText = "play";
|
|
|
|
};
|
2024-07-20 22:57:04 +01:00
|
|
|
currentAudio.onended = () => {
|
2024-07-21 21:39:29 +01:00
|
|
|
currentVolume = 0;
|
2024-07-20 22:57:04 +01:00
|
|
|
playAudio();
|
|
|
|
};
|
|
|
|
currentAudio.volume = 0;
|
2024-07-20 21:18:41 +01:00
|
|
|
|
|
|
|
currentAudio.play();
|
2024-07-20 22:16:16 +01:00
|
|
|
|
|
|
|
fadeIn();
|
|
|
|
setTimeout(() => {
|
|
|
|
fadeOut();
|
|
|
|
}, AUDIO_DURATION_MS - CROSSFADE_DURATION_MS);
|
2024-07-20 21:18:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
function pauseAudio() {
|
|
|
|
currentAudio.pause();
|
2024-07-20 22:57:04 +01:00
|
|
|
currentAudio.volume = 0;
|
2024-07-21 21:39:29 +01:00
|
|
|
currentVolume = 0;
|
2024-07-20 21:18:41 +01:00
|
|
|
}
|
|
|
|
|
2024-07-20 22:16:16 +01:00
|
|
|
function fadeIn() {
|
2024-07-21 21:39:29 +01:00
|
|
|
isFading = true;
|
|
|
|
|
2024-07-20 22:17:04 +01:00
|
|
|
// volume ranges from 0 to 100, this determines by how much the volume number
|
2024-07-20 22:16:16 +01:00
|
|
|
// should be incremented at every step of the fade in
|
2024-07-21 21:39:29 +01:00
|
|
|
const volumeStep =
|
|
|
|
maxVolume / (CROSSFADE_DURATION_MS / CROSSFADE_INTERVAL_MS);
|
2024-07-20 22:16:16 +01:00
|
|
|
const handle = setInterval(() => {
|
2024-07-21 21:39:29 +01:00
|
|
|
currentVolume += volumeStep;
|
|
|
|
if (currentVolume >= maxVolume) {
|
2024-07-20 22:16:16 +01:00
|
|
|
clearInterval(handle);
|
2024-07-21 21:39:29 +01:00
|
|
|
currentVolume = maxVolume;
|
|
|
|
isFading = false;
|
2024-07-20 22:16:16 +01:00
|
|
|
} else {
|
2024-07-21 21:39:29 +01:00
|
|
|
currentAudio.volume = currentVolume / 100;
|
2024-07-20 22:16:16 +01:00
|
|
|
}
|
|
|
|
}, CROSSFADE_INTERVAL_MS);
|
|
|
|
}
|
|
|
|
|
|
|
|
function fadeOut() {
|
2024-07-21 21:39:29 +01:00
|
|
|
isFading = true;
|
|
|
|
|
2024-07-20 22:17:04 +01:00
|
|
|
// volume ranges from 0 to 100, this determines by how much the volume number
|
2024-07-20 22:16:16 +01:00
|
|
|
// should be decremented at every step of the fade out
|
2024-07-21 21:39:29 +01:00
|
|
|
const volumeStep =
|
|
|
|
maxVolume / (CROSSFADE_DURATION_MS / CROSSFADE_INTERVAL_MS);
|
2024-07-20 22:16:16 +01:00
|
|
|
const handle = setInterval(() => {
|
2024-07-21 21:39:29 +01:00
|
|
|
currentVolume -= volumeStep;
|
|
|
|
if (currentVolume <= 0) {
|
2024-07-20 22:16:16 +01:00
|
|
|
clearInterval(handle);
|
2024-07-21 21:39:29 +01:00
|
|
|
currentVolume = 0;
|
|
|
|
isFading = false;
|
2024-07-20 22:16:16 +01:00
|
|
|
} else {
|
2024-07-21 21:39:29 +01:00
|
|
|
currentAudio.volume = currentVolume / 100;
|
2024-07-20 22:16:16 +01:00
|
|
|
}
|
|
|
|
}, CROSSFADE_INTERVAL_MS);
|
|
|
|
}
|
|
|
|
|
2024-07-21 00:31:02 +01:00
|
|
|
function animateCat() {
|
|
|
|
let current = 0;
|
|
|
|
setInterval(() => {
|
|
|
|
if (current === 3) {
|
|
|
|
current = 0;
|
|
|
|
} else {
|
|
|
|
current += 1;
|
|
|
|
}
|
|
|
|
catImg.src = `/images/cat-${current}.png`;
|
|
|
|
}, 500);
|
|
|
|
}
|
|
|
|
|
2024-07-21 19:06:07 +01:00
|
|
|
playBtn.onmousedown = () => {
|
|
|
|
clickAudio.play();
|
|
|
|
document.addEventListener(
|
|
|
|
"mouseup",
|
|
|
|
() => {
|
|
|
|
clickReleaseAudio.play();
|
|
|
|
},
|
|
|
|
{ once: true },
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
2024-07-20 21:18:41 +01:00
|
|
|
playBtn.onclick = () => {
|
|
|
|
if (isPlaying) {
|
|
|
|
pauseAudio();
|
|
|
|
} else {
|
|
|
|
playAudio();
|
|
|
|
}
|
|
|
|
};
|
2024-07-21 00:31:02 +01:00
|
|
|
|
2024-07-21 21:39:29 +01:00
|
|
|
volumeSlider.oninput = () => {
|
|
|
|
maxVolume = volumeSlider.value;
|
|
|
|
currentVolumeLabel.textContent = `${maxVolume}%`;
|
2024-07-22 11:35:33 +01:00
|
|
|
if (!isFading && currentAudio) {
|
2024-07-21 21:39:29 +01:00
|
|
|
currentAudio.volume = maxVolume / 100;
|
|
|
|
currentVolume = maxVolume;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
volumeSlider.value = 100;
|
2024-07-21 00:31:02 +01:00
|
|
|
animateCat();
|