Add folders
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title></title>
|
||||
<script src="main.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1 id="currentClass">None</h1>
|
||||
<div id="btnContainer">
|
||||
<button id="btn-rogue">Rogue</button>
|
||||
<button id="btn-knight">Knight</button>
|
||||
<button id="btn-warrior">Warrior</button>
|
||||
</div>
|
||||
|
||||
<div id="audioContainer"></div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,96 @@
|
||||
const $ = (id) => document.getElementById(id);
|
||||
|
||||
let currentAudio = null;
|
||||
function playAudio(newAudio) {
|
||||
// --------------
|
||||
// HELPERS
|
||||
// --------------
|
||||
const TIME_STEP = 500;
|
||||
const VOL_STEP = .05;
|
||||
|
||||
function fadeOut(audio) {
|
||||
const intervalId = setInterval(() => {
|
||||
audio.volume = Math.max(0, audio.volume - VOL_STEP);
|
||||
if (audio.volume <= 0) {
|
||||
clearInterval(intervalId);
|
||||
}
|
||||
}, TIME_STEP)
|
||||
}
|
||||
|
||||
function fadeIn(audio) {
|
||||
audio.volume = 0;
|
||||
audio.play();
|
||||
const intervalId = setInterval(() => {
|
||||
audio.volume = Math.min(1, audio.volume + VOL_STEP);
|
||||
if (audio.volume >= 1) {
|
||||
clearInterval(intervalId);
|
||||
}
|
||||
}, TIME_STEP)
|
||||
}
|
||||
// --------------
|
||||
|
||||
// --------------
|
||||
// MAIN LOGIC
|
||||
// --------------
|
||||
|
||||
const prevAudio = currentAudio;
|
||||
|
||||
if (prevAudio === newAudio)
|
||||
return;
|
||||
|
||||
if (prevAudio) {
|
||||
fadeOut(prevAudio);
|
||||
}
|
||||
|
||||
fadeIn(newAudio);
|
||||
|
||||
currentAudio = newAudio;
|
||||
// --------------
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", async function() {
|
||||
const $ = (id) => document.getElementById(id);
|
||||
|
||||
const classNames = ["rogue", "knight", "warrior"];
|
||||
const audios = {};
|
||||
|
||||
for (const className of classNames) {
|
||||
const audio = document.createElement("audio");
|
||||
audio.src = `https://bladeandbrawn.com/${className}.ogg`;
|
||||
audio.loop = true;
|
||||
audio.volume = 0;
|
||||
audio.id = `audio-${className}`;
|
||||
$("audioContainer").appendChild(audio);
|
||||
audios[className] = audio;
|
||||
}
|
||||
|
||||
await Promise.all(classNames.map(async (className) => {
|
||||
const audio = audios[className];
|
||||
try {
|
||||
await audio.play();
|
||||
audio.pause();
|
||||
audio.currentTime = 0;
|
||||
} catch (e) {
|
||||
console.warn(`Autoplay failed for ${className}:`, e);
|
||||
}
|
||||
}));
|
||||
|
||||
// Start all in perfect sync
|
||||
classNames.forEach(className => {
|
||||
const audio = audios[className];
|
||||
audio.currentTime = 0;
|
||||
audio.play();
|
||||
});
|
||||
|
||||
// Hook up buttons
|
||||
classNames.forEach(className => {
|
||||
$(`btn-${className}`).onclick = () => {
|
||||
$("currentClass").textContent = className;
|
||||
playAudio(audios[className]);
|
||||
};
|
||||
});
|
||||
|
||||
// Set initial state
|
||||
$("currentClass").textContent = "rogue";
|
||||
playAudio(audios["rogue"]);
|
||||
});
|
||||
Reference in New Issue
Block a user