Files
Kinderspiele/game-server/public/spiele/buchstaben.html
T
2026-04-26 09:44:19 +02:00

246 lines
9.5 KiB
HTML

<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>Buchstaben nachmalen - KinderWelt</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; user-select: none; }
body {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh; display: flex; flex-direction: column; align-items: center;
font-family: 'Comic Sans MS', cursive, sans-serif; padding: 10px;
}
h1 { color: white; margin-bottom: 10px; font-size: 22px; }
.instruction { color: white; font-size: 18px; margin-bottom: 10px; text-align: center; }
.main-area {
display: flex; flex-direction: column; align-items: center; gap: 15px;
}
.letter-section {
display: flex; flex-direction: column; align-items: center; gap: 10px;
}
.target-letter {
font-size: 80px; background: white; border-radius: 15px;
padding: 10px 30px; box-shadow: 0 5px 15px rgba(0,0,0,0.2);
}
.arrow { font-size: 30px; color: white; }
.drawing-area { position: relative; }
#drawCanvas {
background: white; border: 3px solid #4ade80; border-radius: 15px;
box-shadow: 0 5px 15px rgba(0,0,0,0.2); touch-action: none;
}
.template-overlay {
position: absolute; top: 0; left: 0; pointer-events: none;
font-size: 200px; color: rgba(200,200,200,0.3); text-align: center;
line-height: 300px; width: 300px; height: 300px;
}
.letter-grid {
display: grid; grid-template-columns: repeat(10, 1fr);
gap: 5px; max-width: 500px; width: 100%; margin: 10px 0;
}
.letter-btn {
background: rgba(255,255,255,0.9); border: none; border-radius: 8px;
padding: 10px 5px; font-size: 20px; cursor: pointer; font-family: inherit;
transition: all 0.2s;
}
.letter-btn:hover { background: white; transform: scale(1.1); }
.letter-btn.active { background: #4ade80; color: white; }
.controls { display: flex; gap: 15px; margin-top: 10px; flex-wrap: wrap; justify-content: center; }
.btn {
background: white; border: none; border-radius: 10px; padding: 12px 25px;
font-size: 16px; cursor: pointer; font-family: inherit; font-weight: bold;
}
.btn-check { background: #4ade80; color: white; }
.btn-clear { background: #feca57; }
.btn-back { background: #ff6b6b; color: white; text-decoration: none; }
.feedback {
font-size: 24px; margin: 10px 0; min-height: 40px; font-weight: bold;
color: white; text-align: center;
}
.score { color: white; font-size: 18px; margin-top: 5px; }
</style>
</head>
<body>
<h1>🔤 Buchstaben nachmalen</h1>
<div class="instruction" id="instruction">Male den Buchstaben nach!</div>
<div class="main-area">
<div class="letter-section">
<div class="target-letter" id="targetLetter">A</div>
<div class="arrow">⬇️</div>
<div class="drawing-area">
<canvas id="drawCanvas" width="300" height="300"></canvas>
<div class="template-overlay" id="templateOverlay">A</div>
</div>
</div>
</div>
<div class="feedback" id="feedback"></div>
<div class="score">Richtig: <span id="correctCount">0</span></div>
<div class="controls">
<button class="btn btn-check" onclick="checkDrawing()">✓ Fertig!</button>
<button class="btn btn-clear" onclick="clearCanvas()">🗑️ Löschen</button>
<button class="btn" onclick="nextLetter()">🔄 Nächster</button>
<a href="../index.html" class="btn btn-back">⬅️ Zurück</a>
</div>
<div class="letter-grid" id="letterGrid"></div>
<script>
const letters = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','Ä','Ö','Ü'];
const synth = window.speechSynthesis;
let currentLetter = 'A';
let currentIndex = 0;
let isDrawing = false;
let correctCount = 0;
let hasDrawn = false;
const canvas = document.getElementById('drawCanvas');
const ctx = canvas.getContext('2d');
const templateOverlay = document.getElementById('templateOverlay');
// Setup canvas
ctx.lineCap = 'round';
ctx.lineJoin = 'round';
ctx.lineWidth = 8;
ctx.strokeStyle = '#333';
function initGrid() {
const grid = document.getElementById('letterGrid');
letters.forEach((letter, index) => {
const btn = document.createElement('button');
btn.className = 'letter-btn';
btn.textContent = letter;
btn.onclick = () => selectLetter(index);
grid.appendChild(btn);
});
}
function selectLetter(index) {
currentIndex = index;
currentLetter = letters[index];
updateDisplay();
}
function updateDisplay() {
document.getElementById('targetLetter').textContent = currentLetter;
templateOverlay.textContent = currentLetter;
document.getElementById('instruction').textContent = `Male den Buchstaben "${currentLetter}" nach!`;
// Highlight
document.querySelectorAll('.letter-btn').forEach((btn, i) => {
btn.classList.toggle('active', i === currentIndex);
});
clearCanvas();
speak(`Male den Buchstaben ${currentLetter}`);
}
function nextLetter() {
currentIndex = (currentIndex + 1) % letters.length;
selectLetter(currentIndex);
}
// Drawing functions
function getPos(e) {
const rect = canvas.getBoundingClientRect();
const clientX = e.touches ? e.touches[0].clientX : e.clientX;
const clientY = e.touches ? e.touches[0].clientY : e.clientY;
return {
x: clientX - rect.left,
y: clientY - rect.top
};
}
function startDraw(e) {
isDrawing = true;
hasDrawn = true;
const pos = getPos(e);
ctx.beginPath();
ctx.moveTo(pos.x, pos.y);
e.preventDefault();
}
function draw(e) {
if (!isDrawing) return;
const pos = getPos(e);
ctx.lineTo(pos.x, pos.y);
ctx.stroke();
e.preventDefault();
}
function stopDraw() {
isDrawing = false;
}
function clearCanvas() {
ctx.fillStyle = 'white';
ctx.fillRect(0, 0, canvas.width, canvas.height);
hasDrawn = false;
document.getElementById('feedback').textContent = '';
}
function checkDrawing() {
if (!hasDrawn) {
document.getElementById('feedback').textContent = '⚠️ Male erst etwas!';
return;
}
// Einfache Prüfung: Hat der Benutzer genug gezeichnet?
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const pixels = imageData.data;
let drawnPixels = 0;
// Zähle nicht-weiße Pixel
for (let i = 3; i < pixels.length; i += 4) {
if (pixels[i] > 0) drawnPixels++;
}
// Mindestens 500 Pixel müssen gezeichnet sein
const threshold = 500;
if (drawnPixels > threshold) {
correctCount++;
document.getElementById('correctCount').textContent = correctCount;
document.getElementById('feedback').textContent = '🌟 Sehr gut! Super gemalt!';
document.getElementById('feedback').style.color = '#4ade80';
speak(`Sehr gut! Du hast den Buchstaben ${currentLetter} toll gemalt!`);
// Automatisch nächster nach 2 Sekunden
setTimeout(nextLetter, 2000);
} else {
document.getElementById('feedback').textContent = '✏️ Versuch es nochmal! Male den Buchstaben größer.';
document.getElementById('feedback').style.color = '#feca57';
speak('Versuch es nochmal. Male den Buchstaben größer und deutlicher.');
}
}
function speak(text) {
if (!synth) return;
const utterance = new SpeechSynthesisUtterance(text);
utterance.lang = 'de-DE';
utterance.rate = 0.8;
utterance.pitch = 1.2;
synth.speak(utterance);
}
// Event listeners
canvas.addEventListener('mousedown', startDraw);
canvas.addEventListener('mousemove', draw);
canvas.addEventListener('mouseup', stopDraw);
canvas.addEventListener('mouseout', stopDraw);
canvas.addEventListener('touchstart', startDraw);
canvas.addEventListener('touchmove', draw);
canvas.addEventListener('touchend', stopDraw);
// Init
initGrid();
clearCanvas();
updateDisplay();
</script>
</body>
</html>