fix(rosto): parado mais humano; tonto com espirais e bocejo com a mão
Parado ele vivia escondendo o rosto: a IA local (Qwen 0.6B) reagia a cada som ou "sozinho" a cada 20-60 s e repetia 'esconder' apesar do "varie". - IA local: cada evento só oferece gestos que combinam (barulho: susto ou olhar; movimento: olhar e acenar), os dois últimos ficam fora do enum, no máximo a cada 45 s, não interrompe atividade e, com o modo vida ligado, não reage a "sozinho". - Sem ninguém olhando (sem movimento/PIR há 3 min) nada de gesto "para alguém" (acenar, tímido, esconder...): ele vive a vida dele e começa atividades com mais frequência. - Gestos soltos no celular: quase sempre sutis (olhar de lado, piscar devagar), gesto grande raro e nunca repetido em seguida. - Olhar em repouso com fixações e sacadas em vez do vaivém contínuo. - Tonto: espirais girando no lugar dos olhos (todos os rostos, inclusive Matriz) e boca de "ó". Bocejo: mão na frente da boca com tapinhas e Zzz subindo. As mãos agora aparecem também quando o gesto vem sozinho. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -107,7 +107,20 @@
|
||||
}
|
||||
|
||||
// Olho plano (vivo, bloco, matriz): corpo + pálpebras recortadas (transparentes).
|
||||
// Tonto: uma espiral girando no lugar de cada olho (cada um gira para um lado, como no emoji 😵💫).
|
||||
function espiral(c, o, cx, cy, R, lado) {
|
||||
const voltas = 2.75, giro = (o.t || 0) * 7 * lado;
|
||||
c.save(); c.strokeStyle = css(o.cor); c.lineWidth = Math.max(2, R * 0.17); c.lineCap = 'round';
|
||||
c.beginPath();
|
||||
for (let th = 0; th <= voltas * Math.PI * 2; th += 0.22) {
|
||||
const rr = R * th / (voltas * Math.PI * 2), a = th * lado + giro;
|
||||
if (th) c.lineTo(cx + Math.cos(a) * rr, cy + Math.sin(a) * rr); else c.moveTo(cx, cy);
|
||||
}
|
||||
c.stroke(); c.restore();
|
||||
}
|
||||
|
||||
function olhoPlano(c, o, p, est, e) {
|
||||
if (o.espiral) { espiral(c, o, p.cx, p.cy, Math.min(est.w, est.h) * p.ry * 0.5, p.lado || 1); return; }
|
||||
const respira = 1 + 0.012 * Math.sin(o.t * 1.4);
|
||||
const temConteudo = !!(o.icone || o.desenho);
|
||||
if (temConteudo) e = { top: 0, slant: 0, bot: 0, coracao: 0 };
|
||||
@@ -162,6 +175,7 @@
|
||||
|
||||
// Olho lente: esclera, íris, pupila que dilata e pálpebras de metal.
|
||||
function olhoLente(c, o, p, est, e) {
|
||||
if (o.espiral) { espiral(c, o, p.cx, p.cy, est.w * p.ry * 0.5, p.lado || 1); return; }
|
||||
const R = est.w * p.ry * 0.5 * Math.max(1, p.ab) * (1 + 0.01 * Math.sin(o.t * 1.4));
|
||||
const fecha = Math.min(1, Math.max(o.icone || o.desenho ? 0 : e.top, 1 - Math.min(1, p.ab)));
|
||||
c.save();
|
||||
@@ -289,7 +303,7 @@
|
||||
// ------------------------------------------------------------------ mãos
|
||||
// Mãozinhas na cor dos olhos que sobem da borda da tela. Duração casada com as sequências
|
||||
// de rosto de mesmo nome no carinha.html.
|
||||
const DUR_MAOS = { esconder: 2.6, espiar: 3.2, acenar: 2.4, pensar: 2.8 };
|
||||
const DUR_MAOS = { esconder: 2.6, espiar: 3.2, acenar: 2.4, pensar: 2.8, bocejar: 2.1 };
|
||||
const maos = { modo: null, t0: null };
|
||||
const suave = (x) => { x = Math.max(0, Math.min(1, x)); return x * x * (3 - 2 * x); };
|
||||
const faixaDe = (k, a, b) => suave((k - a) / (b - a)); // 0→1 entre a e b
|
||||
@@ -387,6 +401,16 @@
|
||||
const y = fora + (y0 - fora) * v;
|
||||
const balanco = k > 0.22 && k < 0.82 ? Math.sin((k - 0.22) * Math.PI * 7) * 0.32 : 0;
|
||||
mao(c, o, x, y, s * 0.95, -0.18 + balanco, -1, 0, 1, false, true);
|
||||
} else if (maos.modo === 'bocejar') {
|
||||
// mão na frente da boca, com tapinhas, e os Zzz subindo do olho
|
||||
const ida = voltinha(k / 0.25), volta = faixaDe(k, 0.78, 1);
|
||||
const v = Math.max(0, Math.min(1.08, ida)) * (1 - volta);
|
||||
const bx = (e.cx + d.cx) / 2 + e.ry * 0.12, by = e.cy + e.ry * 1.2;
|
||||
const tapa = k > 0.3 && k < 0.75 ? Math.abs(Math.sin((k - 0.3) * Math.PI * 6)) * s * 0.12 : 0;
|
||||
mao(c, o, bx + e.ry * 0.5 * (1 - Math.min(1, v)), fora + (by + s * 0.55 - fora) * v + tapa, s * 0.9, -0.22, -1, 0.15, 0, false, true, true);
|
||||
c.save(); c.globalAlpha *= Math.min(1, v);
|
||||
desenharZzz(c, Object.assign({}, o, { dormindo: true }), olhos, 0.8);
|
||||
c.restore();
|
||||
} else if (maos.modo === 'pensar') {
|
||||
const ida = voltinha(k / 0.22), volta = faixaDe(k, 0.82, 1);
|
||||
const v = Math.max(0, Math.min(1.08, ida)) * (1 - volta);
|
||||
|
||||
Reference in New Issue
Block a user