JSFiddle - React, Tailwind, and code Playground
by gustav75
HTML
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Virtuelles Drum Kit</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="drum-kit">
<div class="drum" data-sound="kick" data-key="A">Kick (A)</div>
<div class="drum" data-sound="snare" data-key="S">Snare (S)</div>
<div class="drum" data-sound="hihat" data-key="D">Hi-Hat (D)</div>
</div>
<div id="controls">
<label for="tempo">Tempo (BPM):</label>
<input type="number" id="tempo" value="90" min="30" max="300">
</div>
<button id="record-button">Aufnehmen</button>
<button id="playback-button" disabled>Abspielen</button>
<button id="stop-button" disabled>Stopp</button>
<script src="script.js"></script>
</body>
</html>
CSS
body {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: #333;
}
#drum-kit {
display: flex;
gap: 20px;
}
.drum {
width: 100px;
height: 100px;
background-color: #444;
color: white;
display: flex;
justify-content: center;
align-items: center;
border-radius: 10px;
cursor: pointer;
user-select: none;
transition: background-color 0.1s;
}
.drum:active {
background-color: #666;
}
#controls {
margin-top: 20px;
}
button {
margin-top: 20px;
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
}
JavaScript
const sounds = {
kick: 'https://static.wixstatic.com/mp3/efdc4b_ffbd0fa4b6374aad9c4c593531698326.mp3',
snare: 'https://static.wixstatic.com/mp3/efdc4b_c77562d756d046c686edeaf608ffac4b.mp3',
hihat: 'https://static.wixstatic.com/mp3/efdc4b_7c93e3de7fd84f15adab1fcf9e1246f3.mp3',
click: 'https://static.wixstatic.com/mp3/efdc4b_a086a0ea9e8c44d1bb791060977c4849.mp3'
};
const recordButton = document.getElementById('record-button');
const playbackButton = document.getElementById('playback-button');
const stopButton = document.getElementById('stop-button');
const tempoInput = document.getElementById('tempo');
let recording = [];
let isRecording = false;
let isPlaying = false;
let startTime;
let tempo = 90; // Standardtempo in BPM
let clickInterval;
let playbackInterval;
let preCountIn = 4; // 4 Schläge zum Vorzählen
let maxDuration;
tempoInput.addEventListener('input', () => {
tempo = parseInt(tempoInput.value, 10);
maxDuration = (480000 / tempo); // 8 Takte = 8 * 60000ms / BPM
});
document.querySelectorAll('.drum').forEach(drum => {
drum.addEventListener('mousedown', () => playSound(drum));
});
document.addEventListener('keydown', (event) => {
const drum = document.querySelector(`.drum[data-key="${event.key.toUpperCase()}"]`);
if (drum) {
playSound(drum);
}
});
recordButton.addEventListener('click', () => {
if (!isRecording) {
startRecording();
}
});
playbackButton.addEventListener('click', playRecordingLoop);
stopButton.addEventListener('click', stopPlayback);
function playSound(drum) {
const sound = new Audio(sounds[drum.dataset.sound]);
sound.play();
if (isRecording) {
const time = Date.now() - startTime;
if (time <= maxDuration) {
recording.push({ sound: drum.dataset.sound, time });
}
}
}
function startRecording() {
recording = [];
isRecording = true;
recordButton.textContent = "Aufnahme läuft...";
playbackButton.disabled =...