const label = document.getElementById("label"); const eyes = Array.from(document.querySelectorAll(".eye")); const mouthShape = document.querySelector(".mouth-shape"); let current = "neutral"; function setEmotion(name) { const safe = String(name || "neutral") .toLowerCase() .replace(/[^a-z0-9_-]/g, ""); current = safe; document.body.className = `emotion-${safe}`; label.textContent = safe; // Sonderfall: surprised -> O-Mund aktivieren if (safe === "surprised") document.body.classList.add("has-omouth"); else document.body.classList.remove("has-omouth"); // sad -> frown pseudo aktivieren (eigene Klasse) if (safe === "sad" || safe === "angry") mouthShape.classList.add("frown"); else mouthShape.classList.remove("frown"); } /** Pupillen bewegen sich sanft, damit es "lebendig" wirkt */ function startPupilWander() { const tick = () => { // kleine zufällige Offsets in Pixel (auf großen Displays reicht das) const x = Math.round((Math.random() * 2 - 1) * 10); const y = Math.round((Math.random() * 2 - 1) * 8); document.documentElement.style.setProperty("--pupil-x", `${x}px`); document.documentElement.style.setProperty("--pupil-y", `${y}px`); // alle 600-1400ms neu const next = 600 + Math.random() * 800; setTimeout(tick, next); }; tick(); } /** Blinzeln: in zufälligen Abständen, manchmal doppelt */ function blinkOnce() { eyes.forEach(e => e.classList.add("blink")); setTimeout(() => eyes.forEach(e => e.classList.remove("blink")), 120); } function startBlinking() { const loop = () => { // sleepy blinzelt öfter/langsamer, angry etwas "härter" let base = 3500; if (current === "sleepy") base = 2200; if (current === "surprised") base = 4200; const next = base + Math.random() * 2200; setTimeout(() => { blinkOnce(); // 15% chance auf Doppelt-Blink if (Math.random() < 0.15) setTimeout(blinkOnce, 220); loop(); }, next); }; loop(); } function connect() { const es = new EventSource("/events"); es.addEventListener("emotion", (e) => setEmotion(e.data)); es.onmessage = (e) => setEmotion(e.data); // fallback es.onerror = () => { es.close(); setTimeout(connect, 1000); }; } connect(); startPupilWander(); startBlinking();