Reputation: 349
Well the thing is this, I already match up the audio with the keys using the atribute "data-key" doing in this way:
const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`);
const key = document.querySelector(`.key[data-key="${e.keyCode}"]`);
Now, I want to do the same but with the click of the bottom. I already try like you can see at the end of the snippet of JavaScript, adding a loop for all the buttons, but looks awkward and only run with one audio.
function playSound(e) {
const audio = document.querySelector(`audio[data-key="${e.keyCode}"]`);
const key = document.querySelector(`.key[data-key="${e.keyCode}"]`);
if (!audio) return; // this stop the function from running all together.
audio.currentTime = 0; // this rewind the audio to the start
audio.play(key);
key.classList.add("playing");
}
function removeTransition(e) {
if (e.propertyName !== "transform") return; // skip it if it's not a transform
this.classList.remove("playing");
}
const keys = document.querySelectorAll(".key");
keys.forEach((key) => key.addEventListener("transitionend", removeTransition));
document.addEventListener("keydown", playSound);
for (var i = 0; i < document.querySelectorAll(".beat").length; i++) {
document.querySelectorAll(".beat")[i].addEventListener("click", function () {
var clickAudio = new Audio(
"https://sampleswap.org/samples-ghost/DRUMS%20(FULL%20KITS)/DRUM%20MACHINES/808%20Basic/22[kb]conga1.aif.mp3"
);
clickAudio.play();
});
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="style.css" />
<link
href="https://fonts.googleapis.com/css2?family=Righteous&display=swap"
rel="stylesheet"
/>
<link
href="https://fonts.googleapis.com/css2?family=Wallpoet&display=swap"
rel="stylesheet"
/>
<title>BEATS MACHINE</title>
</head>
<body>
<div class="container-808">
<div class="name-and-display-container">
<div class="display">
<span class="beats-controler">120.BPM</span>
</div>
<div class="name">
<h1>Rhythm Designer</h1>
<h3>RD-808</h3>
</div>
</div>
<div class="keys-container">
<button data-key="81" class="key beat first-row">
<kbd>Q</kbd><span class="sound">CONGA</span>
</button>
<button data-key="87" class="key beat first-row">
<kbd>W</kbd><span class="sound">HI HAT</span>
</button>
<button data-key="69" class="key beat first-row">
<kbd>E</kbd><span class="sound">HAND CLAP</span>
</button>
<button data-key="82" class="key beat second-row">
<kbd>R</kbd><span class="sound">HIGH TOM</span>
</button>
<button data-key="84" class="key beat second-row">
<kbd>T</kbd><span class="sound">OPEN HIGH HAT</span>
</button>
<button data-key="89" class="key beat second-row">
<kbd>Y</kbd><span class="sound">SNARE</span>
</button>
<button data-key="85" class="key beat third-row">
<kbd>U</kbd><span class="sound">LOW CONGA</span>
</button>
<button data-key="73" class="key beat third-row">
<kbd>I</kbd><span class="sound">CRASH</span>
</button>
<button data-key="79" class="key beat third-row">
<kbd>O</kbd><span class="sound">TAMB</span>
</button>
<audio
data-key="81"
src="https://sampleswap.org/samples-ghost/DRUMS%20(FULL%20KITS)/DRUM%20MACHINES/808%20Basic/22[kb]conga1.aif.mp3"
></audio>
<audio
data-key="87"
src="https://sampleswap.org/samples-ghost/DRUMS%20(FULL%20KITS)/DRUM%20MACHINES/808%20Basic/4[kb]cl_hihat.aif.mp3"
></audio>
<audio
data-key="69"
src="https://sampleswap.org/samples-ghost/DRUMS%20(FULL%20KITS)/DRUM%20MACHINES/808%20Basic/31[kb]handclap.aif.mp3"
></audio>
<audio
data-key="82"
src="https://sampleswap.org/samples-ghost/DRUMS%20(FULL%20KITS)/DRUM%20MACHINES/808%20Basic/17[kb]hightom.aif.mp3"
></audio>
<audio
data-key="84"
src="https://sampleswap.org/samples-ghost/DRUMS%20(FULL%20KITS)/DRUM%20MACHINES/808%20Basic/51[kb]open_hh.aif.mp3"
></audio>
<audio
data-key="89"
src="https://sampleswap.org/samples-ghost/DRUMS%20(FULL%20KITS)/DRUM%20MACHINES/808%20Basic/8[kb]snare.aif.mp3"
></audio>
<audio
data-key="85"
src="https://sampleswap.org/samples-ghost/DRUMS%20(FULL%20KITS)/DRUM%20MACHINES/80s%20Drum%20Machine/16[kb]80s-LOWCONGA.aif.mp3"
></audio>
<audio
data-key="73"
src="https://sampleswap.org/samples-ghost/DRUMS%20(FULL%20KITS)/DRUM%20MACHINES/80s%20Drum%20Machine/83[kb]80s-CRASH1.aif.mp3"
></audio>
<audio
data-key="79"
src="https://sampleswap.org/samples-ghost/DRUMS%20(FULL%20KITS)/DRUM%20MACHINES/80s%20Drum%20Machine/20[kb]80s-TAMB1.aif.mp3"
></audio>
</div>
</div>
<script src="index.js"></script>
</body>
</html>
Upvotes: 1
Views: 480
Reputation: 206121
Event.key
or rather, in your specific case, since you'd like to internationalize your keyboard - use Event.code - BTW, I'm on a QWERTZ keyboard, so finally the below should work for my keyboard as well as for yours.path
string with your route to your sounds.sounds
object holding the minimal known data, just like a library - where every key is actually a Keyboard Event.code
onended
Event to remove the "playing" CSS class from your buttonsconst path = "https://sampleswap.org/samples-ghost/DRUMS%20(FULL%20KITS)/DRUM%20MACHINES/";
const sounds = {
"KeyQ": {src:"808%20Basic/22[kb]conga1.aif.mp3", name:"CONGA"},
"KeyW": {src:"808%20Basic/4[kb]cl_hihat.aif.mp3", name:"HI HAT"},
"KeyE": {src:"808%20Basic/31[kb]handclap.aif.mp3", name:"HAND CLAP"},
"KeyR": {src:"808%20Basic/17[kb]hightom.aif.mp3", name:"HIGH TOM"},
"KeyT": {src:"808%20Basic/51[kb]open_hh.aif.mp3", name:"OPEN HIGH HAT"},
"KeyY": {src:"808%20Basic/8[kb]snare.aif.mp3", name:"SNARE"},
"KeyU": {src:"80s%20Drum%20Machine/16[kb]80s-LOWCONGA.aif.mp3", name:"LOW CONGA"},
"KeyI": {src:"80s%20Drum%20Machine/83[kb]80s-CRASH1.aif.mp3", name:"CRASH"},
"KeyO": {src:"80s%20Drum%20Machine/20[kb]80s-TAMB1.aif.mp3", name:"TAMB"},
};
const ELNew = (sel, attr) => Object.assign(document.createElement(sel), attr || {});
const EL_keys = document.querySelector(".keys-container");
const keyBtn = (k) => ELNew("button", {
classList: "key beat",
type: "button",
innerHTML: `<kbd>${k.replace("Key","")}</kbd><span class="sound">${sounds[k].name}</span>`,
onmousedown: () => playSound(k)
});
// PRELOAD ALL SOUNDS. You dont' want loading delays, right?!
// Also... CREATE KEY BUTTONS as well.
Object.keys(sounds).forEach(k => {
const soundObj = sounds[k];
soundObj.audio = new Audio();
soundObj.audio.src = path + soundObj.src;
soundObj.audio.preload = true;
soundObj.audio.load();
soundObj.button = keyBtn(k); // Create button
EL_keys.append(soundObj.button); // Append button
});
function playSound(k) {
if (!(k in sounds)) return;
const obj = sounds[k];
obj.audio.currentTime = 0; // this rewind the audio to the start
obj.audio.play();
// Animate button:
obj.button.classList.add("playing");
obj.audio.addEventListener("ended", () => obj.button.classList.remove("playing"), {once: true});
}
document.addEventListener("keydown", (ev) => playSound(ev.code));
.key kbd { display: inline-block; text-transform: uppercase; padding: 0.5em; margin-right: 5px; }
.key { transition: 0.5s; }
.key.playing { box-shadow: 0 0 100px #0bf, inset 0 0 2em #0bf; }
<div class="keys-container"></div>
TODO: while loading sounds (see: "PRELOAD ALL SOUNDS") you could create a loading bar. Have an idea by reading this link
PRO-TIP: Since browsers only allow playing sounds after a user gesture like a click, create a button i.e: "Load App" that, by clicking, plays a silent (muted) audio. That way you'll circumvent the browser from that restriction of preloading and playing your other sounds.
Upvotes: 1
Reputation: 4435
You can clean it up nicely by using the forEach()
funciton:
document.querySelectorAll(".beat").forEach(el => {
el.addEventListener("click", function () {
clickAudio.play();
});
});
Upvotes: 0
Reputation: 2829
You can use event delegation so attach the event listener to the container and on each click on the span element we get the data-key of the button element(its parent) and then search for the audio element that has the same data-key attribute and play it
document.querySelector(".keys-container").onclick = function(e) {
if(e.target.nodeName === "SPAN") {
var key = e.target.parentElement.getAttribute("data-key");
document.querySelector(`audio[data-key='${key}']`).play();
}
}
<div class="container-808">
<div class="name-and-display-container">
<div class="display">
<span class="beats-controler">120.BPM</span>
</div>
<div class="name">
<h1>Rhythm Designer</h1>
<h3>RD-808</h3>
</div>
</div>
<div class="keys-container">
<button data-key="81" class="key beat first-row">
<kbd>Q</kbd><span class="sound">CONGA</span>
</button>
<button data-key="87" class="key beat first-row">
<kbd>W</kbd><span class="sound">HI HAT</span>
</button>
<button data-key="69" class="key beat first-row">
<kbd>E</kbd><span class="sound">HAND CLAP</span>
</button>
<button data-key="82" class="key beat second-row">
<kbd>R</kbd><span class="sound">HIGH TOM</span>
</button>
<button data-key="84" class="key beat second-row">
<kbd>T</kbd><span class="sound">OPEN HIGH HAT</span>
</button>
<button data-key="89" class="key beat second-row">
<kbd>Y</kbd><span class="sound">SNARE</span>
</button>
<button data-key="85" class="key beat third-row">
<kbd>U</kbd><span class="sound">LOW CONGA</span>
</button>
<button data-key="73" class="key beat third-row">
<kbd>I</kbd><span class="sound">CRASH</span>
</button>
<button data-key="79" class="key beat third-row">
<kbd>O</kbd><span class="sound">TAMB</span>
</button>
<audio
data-key="81"
src="https://sampleswap.org/samples-ghost/DRUMS%20(FULL%20KITS)/DRUM%20MACHINES/808%20Basic/22[kb]conga1.aif.mp3"
></audio>
<audio
data-key="87"
src="https://sampleswap.org/samples-ghost/DRUMS%20(FULL%20KITS)/DRUM%20MACHINES/808%20Basic/4[kb]cl_hihat.aif.mp3"
></audio>
<audio
data-key="69"
src="https://sampleswap.org/samples-ghost/DRUMS%20(FULL%20KITS)/DRUM%20MACHINES/808%20Basic/31[kb]handclap.aif.mp3"
></audio>
<audio
data-key="82"
src="https://sampleswap.org/samples-ghost/DRUMS%20(FULL%20KITS)/DRUM%20MACHINES/808%20Basic/17[kb]hightom.aif.mp3"
></audio>
<audio
data-key="84"
src="https://sampleswap.org/samples-ghost/DRUMS%20(FULL%20KITS)/DRUM%20MACHINES/808%20Basic/51[kb]open_hh.aif.mp3"
></audio>
<audio
data-key="89"
src="https://sampleswap.org/samples-ghost/DRUMS%20(FULL%20KITS)/DRUM%20MACHINES/808%20Basic/8[kb]snare.aif.mp3"
></audio>
<audio
data-key="85"
src="https://sampleswap.org/samples-ghost/DRUMS%20(FULL%20KITS)/DRUM%20MACHINES/80s%20Drum%20Machine/16[kb]80s-LOWCONGA.aif.mp3"
></audio>
<audio
data-key="73"
src="https://sampleswap.org/samples-ghost/DRUMS%20(FULL%20KITS)/DRUM%20MACHINES/80s%20Drum%20Machine/83[kb]80s-CRASH1.aif.mp3"
></audio>
<audio
data-key="79"
src="https://sampleswap.org/samples-ghost/DRUMS%20(FULL%20KITS)/DRUM%20MACHINES/80s%20Drum%20Machine/20[kb]80s-TAMB1.aif.mp3"
></audio>
</div>
</div>
Upvotes: 1