tools:rhythmustrainer-fortgeschritten
Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen der Seite angezeigt.
| Nächste Überarbeitung | Vorherige Überarbeitung | ||
| tools:rhythmustrainer-fortgeschritten [10/08/2025 16:07] – angelegt Eric Weber | tools:rhythmustrainer-fortgeschritten [12/08/2025 21:37] (aktuell) – Eric Weber | ||
|---|---|---|---|
| Zeile 121: | Zeile 121: | ||
| .rhythm-trainer .rhythm-notation { | .rhythm-trainer .rhythm-notation { | ||
| font-size: 3em; | font-size: 3em; | ||
| - | font-family: | + | font-family: |
| font-weight: | font-weight: | ||
| color: #2d3748; | color: #2d3748; | ||
| Zeile 188: | Zeile 188: | ||
| color: #4a5568; | color: #4a5568; | ||
| min-width: 80px; | min-width: 80px; | ||
| + | } | ||
| + | |||
| + | .rhythm-trainer .legend { | ||
| + | background: #f0fff4; | ||
| + | border: 1px solid #9ae6b4; | ||
| + | border-radius: | ||
| + | padding: 15px; | ||
| + | margin: 20px 0; | ||
| + | display: flex; | ||
| + | justify-content: | ||
| + | flex-wrap: wrap; | ||
| + | gap: 15px; | ||
| + | } | ||
| + | |||
| + | .rhythm-trainer .legend-item { | ||
| + | display: flex; | ||
| + | align-items: | ||
| + | gap: 8px; | ||
| + | font-size: 14px; | ||
| + | } | ||
| + | |||
| + | .rhythm-trainer .legend-symbol { | ||
| + | font-size: 24px; | ||
| + | font-family: | ||
| + | font-weight: | ||
| } | } | ||
| Zeile 204: | Zeile 229: | ||
| <div class=" | <div class=" | ||
| < | < | ||
| - | < | + | < |
| | | ||
| <div class=" | <div class=" | ||
| < | < | ||
| - | Der Rhythmus kann Viertelnoten (♩), zwei Achtelnoten (♫) oder punktierte Viertelnoten mit Achtelnote (♩. ♪) enthalten. | ||
| Hören Sie sich den Rhythmus an und versuchen Sie ihn zu notieren. Mit " | Hören Sie sich den Rhythmus an und versuchen Sie ihn zu notieren. Mit " | ||
| + | </ | ||
| + | |||
| + | <div class=" | ||
| + | <div class=" | ||
| + | <span class=" | ||
| + | < | ||
| + | </ | ||
| + | <div class=" | ||
| + | <span class=" | ||
| + | < | ||
| + | </ | ||
| </ | </ | ||
| Zeile 260: | Zeile 295: | ||
| let audioContext; | let audioContext; | ||
| let isAudioReady = false; | let isAudioReady = false; | ||
| + | |||
| + | // Note types with their durations and symbols | ||
| + | const noteTypes = [ | ||
| + | { symbol: ' | ||
| + | { symbol: ' | ||
| + | ]; | ||
| async function initAudio() { | async function initAudio() { | ||
| Zeile 268: | Zeile 309: | ||
| } | } | ||
| - | function playBeep(frequency = 800, duration = 0.2, startTime = 0) { | + | function playBeep(frequency = 800, duration = 0.2, startTime = 0, volume = 0.3) { |
| if (!audioContext) return; | if (!audioContext) return; | ||
| | | ||
| Zeile 281: | Zeile 322: | ||
| | | ||
| gainNode.gain.setValueAtTime(0, | gainNode.gain.setValueAtTime(0, | ||
| - | gainNode.gain.linearRampToValueAtTime(0.3, audioContext.currentTime + startTime + 0.01); | + | gainNode.gain.linearRampToValueAtTime(volume, audioContext.currentTime + startTime + 0.01); |
| gainNode.gain.exponentialRampToValueAtTime(0.001, | gainNode.gain.exponentialRampToValueAtTime(0.001, | ||
| | | ||
| Zeile 288: | Zeile 329: | ||
| } | } | ||
| - | // Generate random rhythm | + | // Generate random rhythm |
| function generateRhythm() { | function generateRhythm() { | ||
| currentRhythm = []; | currentRhythm = []; | ||
| - | | + | let totalDuration |
| - | // 0 = quarter note, 1 = two eighth | + | const targetDuration = 4; // 4/4 Takt |
| - | const rand = Math.random(); | + | |
| - | if (rand < 0.33) { | + | // Generate rhythm until we reach exactly 4 beats |
| - | | + | while (totalDuration < targetDuration) { |
| - | } else if (rand < 0.66) { | + | const remainingDuration = targetDuration - totalDuration; |
| - | currentRhythm.push(1); // Two eighth notes | + | |
| - | } else { | + | // Filter |
| - | | + | const validNotes |
| + | | ||
| + | if (validNotes.length === 0) { | ||
| + | // If no note fits, fill with eighth notes | ||
| + | | ||
| + | currentRhythm.push(noteTypes[0]); // Achtelnote | ||
| + | | ||
| + | | ||
| + | | ||
| } | } | ||
| + | | ||
| + | const randomNote = validNotes[Math.floor(Math.random() * validNotes.length)]; | ||
| + | currentRhythm.push(randomNote); | ||
| + | totalDuration += randomNote.duration; | ||
| } | } | ||
| + | | ||
| + | // Reset solution state | ||
| solutionVisible = false; | solutionVisible = false; | ||
| + | showBtn.textContent = ' | ||
| + | | ||
| playBtn.disabled = false; | playBtn.disabled = false; | ||
| showBtn.disabled = false; | showBtn.disabled = false; | ||
| Zeile 311: | Zeile 368: | ||
| // Convert rhythm to notation | // Convert rhythm to notation | ||
| function rhythmToNotation(rhythm) { | function rhythmToNotation(rhythm) { | ||
| - | | + | |
| - | if (beat === 0) return ' | + | |
| - | else if (beat === 1) return ' | + | |
| - | else return '♩. ♪'; | + | |
| - | }).join(' | + | |
| - | return notation; | + | |
| } | } | ||
| - | // Play rhythm | + | // Play rhythm |
| async function playRhythm() { | async function playRhythm() { | ||
| if (isPlaying) return; | if (isPlaying) return; | ||
| Zeile 329: | Zeile 381: | ||
| | | ||
| const beatDuration = 60 / tempo; // Duration of one beat in seconds | const beatDuration = 60 / tempo; // Duration of one beat in seconds | ||
| - | let totalTime = 0; | ||
| | | ||
| - | for (let i = 0; i < currentRhythm.length; i++) { | + | |
| - | // Highlight current beat after delay | + | |
| setTimeout(() => { | setTimeout(() => { | ||
| - | beats.forEach(beat => beat.classList.remove(' | + | beats.forEach(b => b.classList.remove(' |
| - | beats[i].classList.add(' | + | beats[beat].classList.add(' |
| - | }, totalTime | + | }, beat * beatDuration |
| + | } | ||
| + | |||
| + | // Play the rhythm notes | ||
| + | let currentTime = 0; | ||
| + | for (let i = 0; i < currentRhythm.length; | ||
| + | const note = currentRhythm[i]; | ||
| | | ||
| - | | + | // Play the note sound |
| - | | + | playBeep(523, |
| - | playBeep(523, | + | |
| - | } else if (currentRhythm[i] === 1) { | + | |
| - | // Two eighth notes - two shorter beeps | + | |
| - | playBeep(523, | + | |
| - | playBeep(523, | + | |
| - | } else { | + | |
| - | // Dotted quarter + eighth note | + | |
| - | playBeep(523, 0.45, totalTime); // Dotted quarter (3/4 of the beat) | + | |
| - | playBeep(523, 0.15, totalTime + beatDuration * 0.75); // Eighth note (last 1/4 of beat) | + | |
| - | } | + | |
| | | ||
| - | | + | |
| } | } | ||
| | | ||
| - | // Clean up after rhythm is finished | + | // Clean up after rhythm is finished |
| + | const totalTime = 4 * beatDuration; | ||
| setTimeout(() => { | setTimeout(() => { | ||
| beats.forEach(beat => beat.classList.remove(' | beats.forEach(beat => beat.classList.remove(' | ||
| Zeile 363: | Zeile 411: | ||
| } | } | ||
| - | // Show solution | + | // Show/hide solution |
| function showSolution() { | function showSolution() { | ||
| if (!solutionVisible) { | if (!solutionVisible) { | ||
tools/rhythmustrainer-fortgeschritten.1754834826.txt.gz · Zuletzt geändert: von Eric Weber
