Benutzer-Werkzeuge

Webseiten-Werkzeuge


tools:rhythmustrainer-fortgeschritten

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen der Seite angezeigt.

Link zu der Vergleichsansicht

Beide Seiten, vorherige ÜberarbeitungVorherige Überarbeitung
tools:rhythmustrainer-fortgeschritten [12/08/2025 21:29] Eric Webertools:rhythmustrainer-fortgeschritten [12/08/2025 21:37] (aktuell) Eric Weber
Zeile 1: Zeile 1:
-FIXME+<html> 
 +<html lang="de"> 
 +<head> 
 +    <meta charset="UTF-8"> 
 +    <meta name="viewport" content="width=device-width, initial-scale=1.0"> 
 +    <title>Rhythmus-Trainer</title> 
 +    <style> 
 +        .rhythm-trainer { 
 +            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; 
 +            max-width: 800px; 
 +            margin: 0 auto; 
 +            padding: 20px; 
 +            color: #333; 
 +            box-sizing: border-box; 
 +        } 
 + 
 +        .rhythm-trainer * { 
 +            box-sizing: border-box; 
 +        } 
 + 
 +        .rhythm-trainer h1 { 
 +            text-align: center; 
 +            color: #4a5568; 
 +            margin: 0 0 30px 0; 
 +            font-size: 2.5em; 
 +            background: linear-gradient(45deg, #667eea, #764ba2); 
 +            -webkit-background-clip: text; 
 +            -webkit-text-fill-color: transparent; 
 +            background-clip: text; 
 +        } 
 + 
 +        .rhythm-trainer .controls { 
 +            display: flex; 
 +            gap: 15px; 
 +            justify-content: center; 
 +            margin-bottom: 30px; 
 +            flex-wrap: wrap; 
 +        } 
 + 
 +        .rhythm-trainer button { 
 +            padding: 12px 24px; 
 +            font-size: 16px; 
 +            border: none; 
 +            border-radius: 25px; 
 +            cursor: pointer; 
 +            transition: all 0.3s ease; 
 +            font-weight: 600; 
 +            text-transform: uppercase; 
 +            letter-spacing: 1px; 
 +        } 
 + 
 +        .rhythm-trainer .primary-btn { 
 +            background: linear-gradient(45deg, #667eea, #764ba2); 
 +            color: white; 
 +            box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4); 
 +        } 
 + 
 +        .rhythm-trainer .primary-btn:hover { 
 +            transform: translateY(-2px); 
 +            box-shadow: 0 8px 25px rgba(102, 126, 234, 0.6); 
 +        } 
 + 
 +        .rhythm-trainer .secondary-btn { 
 +            background: linear-gradient(45deg, #48bb78, #38a169); 
 +            color: white; 
 +            box-shadow: 0 4px 15px rgba(72, 187, 120, 0.4); 
 +        } 
 + 
 +        .rhythm-trainer .secondary-btn:hover { 
 +            transform: translateY(-2px); 
 +            box-shadow: 0 8px 25px rgba(72, 187, 120, 0.6); 
 +        } 
 + 
 +        .rhythm-trainer .show-btn { 
 +            background: linear-gradient(45deg, #ed8936, #dd6b20); 
 +            color: white; 
 +            box-shadow: 0 4px 15px rgba(237, 137, 54, 0.4); 
 +        } 
 + 
 +        .rhythm-trainer .show-btn:hover { 
 +            transform: translateY(-2px); 
 +            box-shadow: 0 8px 25px rgba(237, 137, 54, 0.6); 
 +        } 
 + 
 +        .rhythm-trainer button:disabled { 
 +            opacity: 0.5; 
 +            cursor: not-allowed; 
 +            transform: none !important; 
 +        } 
 + 
 +        .rhythm-trainer .rhythm-display { 
 +            background: #f7fafc; 
 +            border: 3px solid #e2e8f0; 
 +            border-radius: 15px; 
 +            padding: 30px; 
 +            margin: 20px 0; 
 +            text-align: center; 
 +            min-height: 120px; 
 +            display: flex; 
 +            align-items: center; 
 +            justify-content: center; 
 +            position: relative; 
 +            overflow: hidden; 
 +        } 
 + 
 +        .rhythm-trainer .rhythm-display::before { 
 +            content: ''; 
 +            position: absolute; 
 +            top: 0; 
 +            left: -100%; 
 +            width: 100%; 
 +            height: 100%; 
 +            background: linear-gradient(90deg, transparent, rgba(102, 126, 234, 0.1), transparent); 
 +            transition: left 0.5s ease; 
 +        } 
 + 
 +        .rhythm-trainer .rhythm-display.playing::before { 
 +            left: 100%; 
 +        } 
 + 
 +        .rhythm-trainer .rhythm-notation { 
 +            font-size: 3em; 
 +            font-family: 'Times New Roman', serif; 
 +            font-weight: bold; 
 +            color: #2d3748; 
 +            letter-spacing: 8px; 
 +            text-shadow: 2px 2px 4px rgba(0,0,0,0.1); 
 +        } 
 + 
 +        .rhythm-trainer .beat-indicator { 
 +            display: flex; 
 +            justify-content: center; 
 +            gap: 20px; 
 +            margin: 20px 0; 
 +        } 
 + 
 +        .rhythm-trainer .beat { 
 +            width: 60px; 
 +            height: 60px; 
 +            border: 3px solid #cbd5e0; 
 +            border-radius: 50%; 
 +            display: flex; 
 +            align-items: center; 
 +            justify-content: center; 
 +            font-weight: bold; 
 +            font-size: 20px; 
 +            color: #4a5568; 
 +            transition: all 0.3s ease; 
 +            background: white; 
 +        } 
 + 
 +        .rhythm-trainer .beat.active { 
 +            background: linear-gradient(45deg, #667eea, #764ba2); 
 +            color: white; 
 +            transform: scale(1.2); 
 +            box-shadow: 0 0 20px rgba(102, 126, 234, 0.6); 
 +        } 
 + 
 +        .rhythm-trainer .info { 
 +            background: #ebf8ff; 
 +            border-left: 4px solid #3182ce; 
 +            padding: 15px; 
 +            margin: 20px 0; 
 +            border-radius: 8px; 
 +            font-size: 14px; 
 +            color: #2c5282; 
 +        } 
 + 
 +        .rhythm-trainer .tempo-control { 
 +            display: flex; 
 +            align-items: center; 
 +            justify-content: center; 
 +            gap: 15px; 
 +            margin: 20px 0; 
 +        } 
 + 
 +        .rhythm-trainer .tempo-control input { 
 +            width: 200px; 
 +            height: 8px; 
 +            border-radius: 5px; 
 +            background: #e2e8f0; 
 +            outline: none; 
 +        } 
 + 
 +        .rhythm-trainer .tempo-display { 
 +            font-weight: bold; 
 +            font-size: 18px; 
 +            color: #4a5568; 
 +            min-width: 80px; 
 +        } 
 + 
 +        .rhythm-trainer .legend { 
 +            background: #f0fff4; 
 +            border: 1px solid #9ae6b4; 
 +            border-radius: 10px; 
 +            padding: 15px; 
 +            margin: 20px 0; 
 +            display: flex; 
 +            justify-content: space-around; 
 +            flex-wrap: wrap; 
 +            gap: 15px; 
 +        } 
 + 
 +        .rhythm-trainer .legend-item { 
 +            display: flex; 
 +            align-items: center; 
 +            gap: 8px; 
 +            font-size: 14px; 
 +        } 
 + 
 +        .rhythm-trainer .legend-symbol { 
 +            font-size: 24px; 
 +            font-family: 'Times New Roman', serif; 
 +            font-weight: bold; 
 +        } 
 + 
 +        @keyframes rhythm-pulse { 
 +            0% { transform: scale(1); } 
 +            50% { transform: scale(1.1); } 
 +            100% { transform: scale(1); } 
 +        } 
 + 
 +        .rhythm-trainer .rhythm-display.playing .rhythm-notation { 
 +            animation: rhythm-pulse 0.5s ease-in-out; 
 +        } 
 +    </style> 
 +</head> 
 +<body> 
 +    <div class="rhythm-trainer" style="text-align: center"> 
 +        <h1>🎵 Rhythmus-Trainer</h1> 
 +        <h2>Fortgeschritten (Viertel- und Achtelnoten</h2> 
 +         
 +        <div class="info"> 
 +            <strong>Anleitung:</strong> Klicken Sie auf "Neuen Rhythmus generieren", um einen zufälligen 4/4-Takt zu erstellen.  
 +            Hören Sie sich den Rhythmus an und versuchen Sie ihn zu notieren. Mit "Lösung anzeigen" können Sie Ihre Antwort überprüfen. 
 +        </div> 
 + 
 +        <div class="legend"> 
 +            <div class="legend-item"> 
 +                <span class="legend-symbol">♪</span> 
 +                <span>Achtelnote (0,5 Schläge)</span> 
 +            </div> 
 +            <div class="legend-item"> 
 +                <span class="legend-symbol">♩</span> 
 +                <span>Viertelnote (1 Schlag)</span> 
 +            </div> 
 +        </div> 
 + 
 +        <div class="tempo-control"> 
 +            <label>Tempo:</label> 
 +            <input type="range" id="tempoSlider" min="60" max="180" value="120"> 
 +            <span class="tempo-display" id="tempoDisplay">120 BPM</span> 
 +        </div> 
 + 
 +        <div class="controls"> 
 +            <button class="primary-btn" id="generateBtn">Neuen Rhythmus generieren</button> 
 +            <button class="secondary-btn" id="playBtn" disabled>Rhythmus abspielen</button> 
 +            <button class="show-btn" id="showBtn" disabled>Lösung anzeigen</button> 
 +        </div> 
 + 
 +        <div class="beat-indicator"> 
 +            <div class="beat" id="beat1">1</div> 
 +            <div class="beat" id="beat2">2</div> 
 +            <div class="beat" id="beat3">3</div> 
 +            <div class="beat" id="beat4">4</div> 
 +        </div> 
 + 
 +        <div class="rhythm-display" id="rhythmDisplay"> 
 +            <div class="rhythm-notation" id="rhythmNotation">Klicken Sie auf "Neuen Rhythmus generieren"</div> 
 +        </div> 
 +    </div> 
 + 
 +    <script> 
 +        let currentRhythm = []; 
 +        let isPlaying = false; 
 +        let solutionVisible = false; 
 +        let tempo = 120; 
 + 
 +        // UI Elements 
 +        const generateBtn = document.getElementById('generateBtn'); 
 +        const playBtn = document.getElementById('playBtn'); 
 +        const showBtn = document.getElementById('showBtn'); 
 +        const rhythmDisplay = document.getElementById('rhythmDisplay'); 
 +        const rhythmNotation = document.getElementById('rhythmNotation'); 
 +        const tempoSlider = document.getElementById('tempoSlider'); 
 +        const tempoDisplay = document.getElementById('tempoDisplay'); 
 +        const beats = [ 
 +            document.getElementById('beat1'), 
 +            document.getElementById('beat2'), 
 +            document.getElementById('beat3'), 
 +            document.getElementById('beat4'
 +        ]; 
 + 
 +        // Audio Setup with Web Audio API 
 +        let audioContext; 
 +        let isAudioReady = false; 
 + 
 +        // Note types with their durations and symbols 
 +        const noteTypes = [ 
 +            { symbol: '♪', duration: 0.5, name: 'eighth' },      // Achtelnote 
 +            { symbol: '♩', duration: 1.0, name: 'quarter' },    // Viertelnote 
 +        ]; 
 + 
 +        async function initAudio() { 
 +            if (!isAudioReady) { 
 +                audioContext = new (window.AudioContext || window.webkitAudioContext)(); 
 +                isAudioReady = true; 
 +            } 
 +        } 
 + 
 +        function playBeep(frequency = 800, duration = 0.2, startTime = 0, volume = 0.3) { 
 +            if (!audioContext) return; 
 +             
 +            const oscillator = audioContext.createOscillator(); 
 +            const gainNode = audioContext.createGain(); 
 +             
 +            oscillator.connect(gainNode); 
 +            gainNode.connect(audioContext.destination); 
 +             
 +            oscillator.frequency.setValueAtTime(frequency, audioContext.currentTime + startTime); 
 +            oscillator.type = 'sine'; 
 +             
 +            gainNode.gain.setValueAtTime(0, audioContext.currentTime + startTime); 
 +            gainNode.gain.linearRampToValueAtTime(volume, audioContext.currentTime + startTime + 0.01); 
 +            gainNode.gain.exponentialRampToValueAtTime(0.001, audioContext.currentTime + startTime + duration); 
 +             
 +            oscillator.start(audioContext.currentTime + startTime); 
 +            oscillator.stop(audioContext.currentTime + startTime + duration); 
 +        } 
 + 
 +        // Generate random rhythm that adds up to exactly 4 beats 
 +        function generateRhythm() { 
 +            currentRhythm = []; 
 +            let totalDuration = 0; 
 +            const targetDuration = 4; // 4/4 Takt 
 +             
 +            // Generate rhythm until we reach exactly 4 beats 
 +            while (totalDuration < targetDuration) { 
 +                const remainingDuration = targetDuration - totalDuration; 
 +                 
 +                // Filter notes that fit in remaining time 
 +                const validNotes = noteTypes.filter(note => note.duration <= remainingDuration); 
 +                 
 +                if (validNotes.length === 0) { 
 +                    // If no note fits, fill with eighth notes 
 +                    while (totalDuration < targetDuration) { 
 +                        currentRhythm.push(noteTypes[0]); // Achtelnote 
 +                        totalDuration += 0.5; 
 +                    } 
 +                    break; 
 +                } 
 +                 
 +                const randomNote = validNotes[Math.floor(Math.random() * validNotes.length)]; 
 +                currentRhythm.push(randomNote); 
 +                totalDuration += randomNote.duration; 
 +            } 
 +             
 +            // Reset solution state 
 +            solutionVisible = false; 
 +            showBtn.textContent = 'Lösung anzeigen'; 
 +             
 +            playBtn.disabled = false; 
 +            showBtn.disabled = false; 
 +            rhythmNotation.textContent = "Rhythmus generiert! Hören Sie zu und versuchen Sie ihn zu notieren."; 
 +            rhythmDisplay.classList.remove('playing'); 
 +        } 
 + 
 +        // Convert rhythm to notation 
 +        function rhythmToNotation(rhythm) { 
 +            return rhythm.map(note => note.symbol).join('  '); 
 +        } 
 + 
 +        // Play rhythm with visual beat indication 
 +        async function playRhythm() { 
 +            if (isPlaying) return; 
 +             
 +            await initAudio(); 
 +            isPlaying = true; 
 +            playBtn.disabled = true; 
 +            rhythmDisplay.classList.add('playing'); 
 +             
 +            const beatDuration = 60 / tempo; // Duration of one beat in seconds 
 +             
 +            // Highlight beats independently (every beat for 4 beats) 
 +            for (let beat = 0; beat < 4; beat++) { 
 +                setTimeout(() => { 
 +                    beats.forEach(b => b.classList.remove('active')); 
 +                    beats[beat].classList.add('active'); 
 +                }, beat * beatDuration * 1000); 
 +            } 
 +             
 +            // Play the rhythm notes 
 +            let currentTime = 0; 
 +            for (let i = 0; i < currentRhythm.length; i++) { 
 +                const note = currentRhythm[i]; 
 +                 
 +                // Play the note sound 
 +                playBeep(523, Math.min(note.duration * beatDuration * 0.8, 0.4), currentTime * beatDuration, 0.3); 
 +                 
 +                currentTime += note.duration; 
 +            } 
 +             
 +            // Clean up after rhythm is finished (after 4 beats) 
 +            const totalTime = 4 * beatDuration; 
 +            setTimeout(() => { 
 +                beats.forEach(beat => beat.classList.remove('active')); 
 +                rhythmDisplay.classList.remove('playing'); 
 +                isPlaying = false; 
 +                playBtn.disabled = false; 
 +            }, totalTime * 1000 + 200); 
 +        } 
 + 
 +        // Show/hide solution 
 +        function showSolution() { 
 +            if (!solutionVisible) { 
 +                const notation = rhythmToNotation(currentRhythm); 
 +                rhythmNotation.textContent = notation; 
 +                solutionVisible = true; 
 +                showBtn.textContent = 'Lösung ausblenden'; 
 +            } else { 
 +                rhythmNotation.textContent = "Rhythmus generiert! Hören Sie zu und versuchen Sie ihn zu notieren."; 
 +                solutionVisible = false; 
 +                showBtn.textContent = 'Lösung anzeigen'; 
 +            } 
 +        } 
 + 
 +        // Update tempo 
 +        function updateTempo() { 
 +            tempo = parseInt(tempoSlider.value); 
 +            tempoDisplay.textContent = tempo + ' BPM'; 
 +        } 
 + 
 +        // Event Listeners 
 +        generateBtn.addEventListener('click', generateRhythm); 
 +        playBtn.addEventListener('click', playRhythm); 
 +        showBtn.addEventListener('click', showSolution); 
 +        tempoSlider.addEventListener('input', updateTempo); 
 + 
 +        // Initialize 
 +        updateTempo(); 
 +    </script> 
 +</body> 
 +</html>
tools/rhythmustrainer-fortgeschritten.1755026998.txt.gz · Zuletzt geändert: von Eric Weber