feat(jogos): telão com contagem regressiva, jogadas lado a lado e resultado
- comando "telao" (validado: texto curto, tom, símbolos permitidos, até 2 lados) e letreiro por cima do rosto: título enorme que estoura e pisca, as duas jogadas (VOCÊ ✊ × ✋ CARINHA), cor por resultado; - pedra, papel e tesoura: 3, 2, 1 piscando, "JÁ!", o que ele leu da sua mão, "VENCI!!!" / "VOCÊ GANHOU!" / "EMPATE!" com placar e o campeão; quantos dedos e achou! também usam o telão; - o cartão do painel mostra o mesmo destaque. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -20,6 +20,27 @@
|
||||
@keyframes aparecerFigura{from{opacity:0}to{opacity:1}}
|
||||
@media(prefers-reduced-motion:reduce){.iconeOlho,.figurinhaDinamica{animation:none}}
|
||||
#fps{position:fixed;left:4px;top:2px;color:#2b3a4a;font:12px monospace;display:none}
|
||||
/* telão dos jogos: por cima do rosto, texto grande na cor dos olhos (o resultado tem cor própria) */
|
||||
#telao{position:fixed;inset:0;z-index:8;display:flex;flex-direction:column;align-items:center;justify-content:center;
|
||||
gap:2vh;background:rgba(0,0,0,.9);font-family:system-ui,sans-serif;color:var(--cor);text-align:center;pointer-events:none}
|
||||
#telao .titulo{font-weight:900;font-size:clamp(40px,24vh,240px);line-height:1;letter-spacing:.02em;
|
||||
text-shadow:0 0 .25em currentColor}
|
||||
#telao .sub{font-size:clamp(14px,6vh,48px);font-weight:600;opacity:.9}
|
||||
#telao .lados{display:flex;align-items:center;gap:5vw}
|
||||
#telao .lado{display:flex;flex-direction:column;align-items:center;gap:1vh;min-width:22vw}
|
||||
#telao .rot{font-size:clamp(12px,5vh,36px);font-weight:700;letter-spacing:.1em;text-transform:uppercase;opacity:.85}
|
||||
#telao .sim{font-size:clamp(40px,26vh,220px);line-height:1}
|
||||
#telao .nome{font-size:clamp(12px,5vh,36px);font-weight:600}
|
||||
#telao .x{font-size:clamp(24px,12vh,110px);font-weight:300;opacity:.7}
|
||||
#telao.tom-eu .titulo{color:#ffd166}
|
||||
#telao.tom-voce .titulo{color:#7ae582}
|
||||
#telao.tom-empate .titulo{color:#cfe8ff}
|
||||
#telao.tom-conta .titulo{font-size:clamp(60px,48vh,420px)}
|
||||
#telao.entra .titulo,#telao.entra .lados{animation:telaoEstoura .45s cubic-bezier(.2,1.6,.4,1)}
|
||||
#telao.piscar.entra .titulo{animation:telaoEstoura .45s cubic-bezier(.2,1.6,.4,1),telaoPisca .5s steps(2) .45s infinite}
|
||||
@keyframes telaoEstoura{from{transform:scale(.3);opacity:0}to{transform:scale(1);opacity:1}}
|
||||
@keyframes telaoPisca{50%{opacity:.25}}
|
||||
@media(prefers-reduced-motion:reduce){#telao *{animation:none!important}}
|
||||
/* sem a placa: placa ✕ celular na cor dos olhos. Deitado, o rosto dormindo fica onde está e o
|
||||
desenho fica em pé no canto direito; em pé, o rosto sobe e o desenho vai embaixo. */
|
||||
#semServidor{position:fixed;right:2.5vw;top:50%;transform:translateY(-50%);width:min(24vw,42vh);
|
||||
@@ -646,6 +667,27 @@ function falarFrase(texto, segundos) { // "dizer ..." do modo vida: le
|
||||
if (window.MotorRosto) window.MotorRosto.faixa('legenda', { texto, segundos: segundos || Math.max(4, Math.min(14, texto.length / 9)) });
|
||||
falar(texto);
|
||||
}
|
||||
/* Telão dos jogos: contagem regressiva piscando, as duas jogadas lado a lado e o resultado grande. */
|
||||
let telaoAte = null;
|
||||
function mostrarTelao(json) {
|
||||
let t;
|
||||
try { t = JSON.parse(json); } catch (e) { return; }
|
||||
let el = document.getElementById('telao');
|
||||
if (!el) { el = document.createElement('div'); el.id = 'telao'; document.body.appendChild(el); }
|
||||
const esc = (s) => String(s || '').replace(/[&<>"]/g, (c) => ({ '&': '&', '<': '<', '>': '>', '"': '"' }[c]));
|
||||
const lados = (t.lados || []).map((l) =>
|
||||
'<div class="lado"><span class="rot">' + esc(l.rotulo) + '</span><span class="sim">' + esc(l.simbolo) + '</span>' +
|
||||
'<span class="nome">' + esc(l.nome) + '</span></div>').join('<div class="x">×</div>');
|
||||
el.className = 'tom-' + (t.tom || 'neutro') + (t.piscar ? ' piscar' : '');
|
||||
el.style.setProperty('--cor', 'rgb(' + CIANO.map(Math.round).join(',') + ')');
|
||||
el.innerHTML = (lados ? '<div class="lados">' + lados + '</div>' : '') +
|
||||
(t.titulo ? '<div class="titulo">' + esc(t.titulo) + '</div>' : '') + (t.sub ? '<div class="sub">' + esc(t.sub) + '</div>' : '');
|
||||
el.hidden = false;
|
||||
void el.offsetWidth; el.classList.add('entra'); // reinicia a animação a cada letreiro
|
||||
if (r.dormindo) r.dormindo = false;
|
||||
clearTimeout(telaoAte);
|
||||
telaoAte = setTimeout(() => { el.hidden = true; }, (t.segundos || 2.5) * 1000);
|
||||
}
|
||||
let olhosAte = null;
|
||||
function mostrarNosOlhos(texto) { // "✌️ 2.5": símbolo nos olhos; "- 0" apaga
|
||||
const i = texto.lastIndexOf(' ');
|
||||
@@ -868,6 +910,7 @@ function trata(ordem) {
|
||||
if (/^aprendi /i.test(bruta)) { contarAprendi(bruta.slice(8).trim()); return; } // sem minúsculas: é uma frase
|
||||
if (/^dizer /i.test(bruta)) { falarFrase(bruta.slice(6).trim()); return; }
|
||||
if (/^olhos /i.test(bruta)) { mostrarNosOlhos(bruta.slice(6).trim()); return; } // jogos: ✊ ✋ ✌️ e números
|
||||
if (/^telao /i.test(bruta)) { mostrarTelao(bruta.slice(6)); return; } // letreiro grande dos jogos
|
||||
ordem = bruta.toLowerCase();
|
||||
if (!ordem) return;
|
||||
if(ordem==='recarregar') {
|
||||
|
||||
Reference in New Issue
Block a user