Alphabet Practice
Listen and type the letter (UK English)
0%
accuracy
Loading...
Total attempts: 0
<span class="text-sm text-gray-500">accuracy</span>
</div>
</div>
</div>
<!-- Interactive Area -->
<div class="space-y-6">
<button id="play-btn" class="w-full bg-teal-500 text-white font-bold py-4 px-6 rounded-xl hover:bg-teal-600 transition-all text-xl shadow-md flex items-center justify-center gap-3">
<i class="fas fa-volume-up"></i>
<span>Play Letter</span>
</button>
<div class="flex flex-col sm:flex-row gap-4">
<input type="text" id="answer-input" maxlength="1" class="flex-grow w-full text-center border-2 border-gray-300 rounded-lg p-4 text-3xl font-mono focus:border-teal-500 focus:ring-teal-500 uppercase" placeholder="?">
<button id="check-btn" class="w-full sm:w-auto bg-gray-800 text-white font-bold py-4 px-8 rounded-xl hover:bg-gray-900 transition-colors">Check</button>
</div>
</div>
<!-- Feedback Message -->
<div id="feedback" class="feedback text-center mt-6 text-xl font-medium">
Loading...
</div>
<div class="text-sm text-gray-500 mt-2">
Total attempts: <span id="total-attempts">0</span>
</div>
</main>
</div>
<footer class="text-center mt-6 text-gray-500 text-sm">
<p>© 2024 Interactive Learning. Happy to help you learn!</p>
</footer>
</div>
<script>
document.addEventListener('DOMContentLoaded', () => {
const playBtn = document.getElementById('play-btn');
const checkBtn = document.getElementById('check-btn');
const answerInput = document.getElementById('answer-input');
const feedbackEl = document.getElementById('feedback');
const scorePercentageEl = document.getElementById('score-percentage');
const totalAttemptsEl = document.getElementById('total-attempts');
const alphabet = 'abcdefghijklmnopqrstuvwxyz';
let currentLetter = '';
let correctAnswers = 0;
let totalAttempts = 0;
let ukVoice = null;
let listenCount = 0; // Track listen attempts per letter
// Find a UK English voice
function loadVoice() {
const voices = speechSynthesis.getVoices();
ukVoice = voices.find(voice => voice.lang === 'en-GB');
// Fallback if no UK voice is found
if (!ukVoice) {
ukVoice = voices.find(voice => voice.lang.startsWith('en-'));
}
if(voices.length > 0 && !ukVoice) {
console.warn("No UK English voice found, using default English voice.");
}
}
// The 'voiceschanged' event fires when the list of voices has been loaded.
speechSynthesis.onvoiceschanged = loadVoice;
// Also call it directly in case the voices are already loaded.
loadVoice();
// Plays the CURRENT letter and handles listen limits
function playCurrentLetter() {
if (!currentLetter) { // Failsafe if called before first round
return;
}
if (listenCount >= 2) {
// This is the 3rd click. Auto-fail.
totalAttempts++;
feedbackEl.innerHTML = `No more listens. The letter was <strong class="uppercase">${currentLetter}</strong>.`;
feedbackEl.className = 'feedback text-center mt-6 text-xl font-medium incorrect';
updateScore();
playBtn.disabled = true;
answerInput.disabled = true;
setTimeout(startNewRound, 2500); // Move to the next round
return;
}
// Use Web Speech API to pronounce the letter
const utterance = new SpeechSynthesisUtterance(currentLetter);
if (ukVoice) {
utterance.voice = ukVoice;
} else {
utterance.lang = 'en-GB';
}
speechSynthesis.speak(utterance);
listenCount++;
if (listenCount === 2) {
playBtn.disabled = true;
playBtn.querySelector('span').textContent = 'Last attempt used';
}
}
// Starts a new round with a new letter
function startNewRound() {
listenCount = 0;
currentLetter = alphabet[Math.floor(Math.random() * alphabet.length)];
playBtn.disabled = false;
playBtn.querySelector('span').textContent = 'Play Letter';
answerInput.disabled = false;
answerInput.value = '';
feedbackEl.textContent = 'Type the letter you heard.';
feedbackEl.className = 'feedback text-center mt-6 text-xl font-medium text-gray-500';
answerInput.focus();
// Automatically play the letter once to start the round
playCurrentLetter();
}
function checkAnswer() {
const userAnswer = answerInput.value.trim().toLowerCase();
if (!currentLetter || answerInput.disabled) {
return; // Don't check if transitioning or not started
}
if (userAnswer === '') {
feedbackEl.textContent = "Please enter a letter.";
feedbackEl.className = 'feedback text-center mt-6 text-xl font-medium incorrect';
return;
}
totalAttempts++;
answerInput.disabled = true; // Disable input after checking
playBtn.disabled = true; // Disable play button while transitioning
if (userAnswer === currentLetter) {
correctAnswers++;
feedbackEl.textContent = 'Correct! 🎉';
feedbackEl.className = 'feedback text-center mt-6 text-xl font-medium correct';
// Start the next round after a short delay
setTimeout(startNewRound, 1500);
} else {
feedbackEl.innerHTML = `Not quite. The correct letter was <strong class="uppercase">${currentLetter}</strong>. Let's try another!`;
feedbackEl.className = 'feedback text-center mt-6 text-xl font-medium incorrect';
// Start the next round after a short delay
setTimeout(startNewRound, 2000);
}
updateScore();
}
function updateScore() {
const percentage = totalAttempts > 0 ? Math.round((correctAnswers / totalAttempts) * 100) : 0;
scorePercentageEl.textContent = `${percentage}%`;
totalAttemptsEl.textContent = totalAttempts;
}
playBtn.addEventListener('click', playCurrentLetter);
checkBtn.addEventListener('click', checkAnswer);
// Allow submitting with Enter key
answerInput.addEventListener('keyup', (e) => {
if (e.key === 'Enter') {
checkBtn.click();
}
});
// Delay the start slightly to ensure voices are loaded
setTimeout(startNewRound, 500);
});
</script>
</body>
</html>
No hay comentarios:
Publicar un comentario