Benutzer-Werkzeuge

Webseiten-Werkzeuge


tools:skalentrainer

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen der Seite angezeigt.

Link zu der Vergleichsansicht

Beide Seiten, vorherige ÜberarbeitungVorherige Überarbeitung
Nächste Überarbeitung
Vorherige Überarbeitung
tools:skalentrainer [15/05/2025 08:59] – ↷ Seitename wurde von tools:skalentrainer-pruefung auf tools:skalentrainer geändert Eric Webertools:skalentrainer [22/05/2025 16:31] (aktuell) Eric Weber
Zeile 1: Zeile 1:
-====== Skalentrainer ====== 
- 
- 
 <html> <html>
 <head> <head>
Zeile 113: Zeile 110:
         #quizSection {         #quizSection {
             display: none;             display: none;
 +        }
 +        .practice-scales-container {
 +            display: grid;
 +            grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
 +            gap: 15px;
 +            margin: 20px 0;
 +        }
 +        .practice-scale-btn {
 +            background-color: #ecf0f1;
 +            color: #2c3e50;
 +            border: 2px solid #bdc3c7;
 +            padding: 15px;
 +            border-radius: 8px;
 +            cursor: pointer;
 +            font-size: 16px;
 +            font-weight: 600;
 +            text-align: center;
 +            transition: all 0.2s;
 +        }
 +        .practice-scale-btn:hover {
 +            background-color: #d5dbdb;
 +            transform: translateY(-2px);
 +            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
 +        }
 +        .practice-scale-btn:active {
 +            transform: translateY(0);
 +            box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
 +        }
 +        .practice-scale-btn.playing {
 +            background-color: #3498db;
 +            color: black;
 +            border-color: #2980b9;
         }         }
         .quiz-options {         .quiz-options {
Zeile 208: Zeile 237:
 </head> </head>
 <body> <body>
 +    <h1>Skalen-Trainer</h1>
          
     <div class="container">     <div class="container">
Zeile 267: Zeile 297:
     <div id="practiceSection" class="container">     <div id="practiceSection" class="container">
         <h2>Übungsmodus</h2>         <h2>Übungsmodus</h2>
-        <div class="flex-row"+        <p>Klicke auf eine Skala, um sie abzuspielen:</p> 
-            <button id="startPracticeBtn">Skalen abspielen</button+         
-            <span class="separator">|</span>+        <div class="practice-scales-container" id="practiceScalesContainer"> 
 +            <!-- Practice scale buttons will be generated here --> 
 +        </div
 +         
 +        <div class="flex-row" style="justify-content: center; margin-top: 20px;">
             <button id="startQuizBtn">Prüfung starten</button>             <button id="startQuizBtn">Prüfung starten</button>
         </div>         </div>
Zeile 306: Zeile 340:
         let audioContext;         let audioContext;
         let currentMode = "easy";         let currentMode = "easy";
-        let allScalesSelected = true;+        let allScalesSelected = false;
         let quizInProgress = false;         let quizInProgress = false;
         let currentQuizQuestion = 0;         let currentQuizQuestion = 0;
Zeile 314: Zeile 348:
         let currentScale;         let currentScale;
         let questionAnswered = false;         let questionAnswered = false;
 +        let currentlyPlayingScale = null;
  
         // Function to stop all audio         // Function to stop all audio
Zeile 321: Zeile 356:
                 resetQuiz();                 resetQuiz();
             }             }
 +            
 +            // Reset practice scale visual state
 +            resetPracticeScaleButtons();
                          
             // If audio context exists, cancel all scheduled sounds             // If audio context exists, cancel all scheduled sounds
Zeile 345: Zeile 383:
                 document.getElementById("nextQuestionBtn").style.display = "none";                 document.getElementById("nextQuestionBtn").style.display = "none";
             }             }
 +        }
 +
 +        // Reset practice scale button visual states
 +        function resetPracticeScaleButtons() {
 +            document.querySelectorAll(".practice-scale-btn").forEach(btn => {
 +                btn.classList.remove("playing");
 +            });
 +            currentlyPlayingScale = null;
         }         }
  
Zeile 351: Zeile 397:
             // Set up event listeners             // Set up event listeners
             document.getElementById("toggleAllBtn").addEventListener("click", toggleAllScales);             document.getElementById("toggleAllBtn").addEventListener("click", toggleAllScales);
-            document.getElementById("startPracticeBtn").addEventListener("click", startPractice); 
             document.getElementById("startQuizBtn").addEventListener("click", startQuiz);             document.getElementById("startQuizBtn").addEventListener("click", startQuiz);
             document.getElementById("playScaleBtn").addEventListener("click", () => playCurrentQuizScale());             document.getElementById("playScaleBtn").addEventListener("click", () => playCurrentQuizScale());
Zeile 363: Zeile 408:
                     setMode(this.dataset.mode);                     setMode(this.dataset.mode);
                     stopAllAudio();                     stopAllAudio();
 +                    updatePracticeScales();
                 });                 });
             });             });
Zeile 368: Zeile 414:
             // Add event listeners to stop audio when settings change             // Add event listeners to stop audio when settings change
             document.querySelectorAll(".scales-container input[type='checkbox']").forEach(checkbox => {             document.querySelectorAll(".scales-container input[type='checkbox']").forEach(checkbox => {
-                checkbox.addEventListener("change", stopAllAudio);+                checkbox.addEventListener("change", function() { 
 +                    stopAllAudio(); 
 +                    updatePracticeScales(); 
 +                });
             });             });
  
-            // Initialize progress markers+            // Initialize progress markers and practice scales
             initializeProgressMarkers();             initializeProgressMarkers();
 +            updatePracticeScales();
         });         });
  
Zeile 385: Zeile 435:
                          
             document.getElementById("toggleAllBtn").textContent = allScalesSelected ? "Alle abwählen" : "Alle auswählen";             document.getElementById("toggleAllBtn").textContent = allScalesSelected ? "Alle abwählen" : "Alle auswählen";
 +            updatePracticeScales();
         }         }
  
Zeile 398: Zeile 449:
                 }                 }
             });             });
 +        }
 +
 +        // Update practice scales display
 +        function updatePracticeScales() {
 +            const container = document.getElementById("practiceScalesContainer");
 +            container.innerHTML = "";
                          
 +            const selectedScales = getSelectedScales();
 +            
 +            if (selectedScales.length === 0) {
 +                container.innerHTML = "<p style='text-align: center; color: #666; grid-column: 1 / -1;'>Bitte wähle mindestens eine Skala aus.</p>";
 +                return;
 +            }
 +            
 +            selectedScales.forEach(scale => {
 +                const button = document.createElement("button");
 +                button.className = "practice-scale-btn";
 +                button.textContent = getScaleName(scale);
 +                button.dataset.scale = scale;
 +                
 +                button.addEventListener("click", function() {
 +                    playPracticeScale(scale, this);
 +                });
 +                
 +                container.appendChild(button);
 +            });
 +        }
  
 +        // Play a practice scale
 +        function playPracticeScale(scale, buttonElement) {
 +            // Reset all button states
 +            resetPracticeScaleButtons();
 +            
 +            // Set current button as playing
 +            buttonElement.classList.add("playing");
 +            currentlyPlayingScale = scale;
 +            
 +            const startNote = getScaleStartNote(scale);
 +            
 +            playScale(scale, startNote, () => {
 +                // Remove playing state after scale finishes
 +                if (currentlyPlayingScale === scale) {
 +                    buttonElement.classList.remove("playing");
 +                    currentlyPlayingScale = null;
 +                }
 +            });
         }         }
  
Zeile 579: Zeile 674:
                 setTimeout(callback, (scaleData.ascending.length + scaleData.descending.length - 1) * noteDuration * 1000);                 setTimeout(callback, (scaleData.ascending.length + scaleData.descending.length - 1) * noteDuration * 1000);
             }             }
-        } 
- 
-        // Practice all selected scales 
-        function startPractice() { 
-            if (!isAnyScaleSelected()) { 
-                alert("Bitte wähle mindestens eine Skala aus."); 
-                return; 
-            } 
-             
-            const scales = getSelectedScales(); 
-            initAudioContext(); 
-             
-            let index = 0; 
-            const playNextScale = () => { 
-                if (index < scales.length) { 
-                    const scale = scales[index]; 
-                    const startNote = getScaleStartNote(scale); 
-                    playScale(scale, startNote, () => { 
-                        index++; 
-                        setTimeout(playNextScale, 500); // 500ms pause between scales 
-                    }); 
-                } 
-            }; 
-             
-            playNextScale(); 
         }         }
  
tools/skalentrainer.1747292374.txt.gz · Zuletzt geändert: von Eric Weber