Colocando o Coelho Branco para funcionar na prática
A maioria dos tutoriais que você encontra na internet começa com um resumo da obra de Lewis Carroll e termina com um código que nunca roda. Eu passei três semanas tentando fazer o coelho de alice no país das maravilhas acompanhar timing de áudio em uma animação canvas, e o problema real não estava na biblioteca -- estava no jeito que o desenho é estruturado frame a frame. Vou explicar como cheguei a um resultado que funciona, sem enrolação.
Por que o coelho de alice no país das maravilhas é mais difícil do que parece
O coelho branco tem uma característica que quebra a maioria dos rigs de animação padrão: ele carrega um relógio de bolso em quase todas as cenas, e esse acessório precisa ter seu próprio loop de movimento independente do braço. Se você tratar o relógio como parte do braço, o movimento fica rígido e sem graça. A solução que encontrei foi separar o coelho em dois grupos articulares -- tronco+pernas em um, e braços+acessórios em outro -- e usar um tweening com easing diferente para cada grupo. Em termos práticos, isso significa que no seu arquivo JSON de rig você vai ter algo como:
"groups": { "body": {"joints": ["hip", "spine", "head"]}, "arms": {"joints": ["l_shoulder", "l_elbow", "l_hand", "r_shoulder", "r_elbow", "r_hand", "pocket_watch"]} Isso parece óbvio depois que você entende, mas em templates prontos na web o relógio costuma estar anexado ao pulso esquerdo sem nenhuma propriedade de offset.
Download do rig básico
Eu preparei um pacote contendo o rig em formato JSON, os spritesheet em PNG com fundo transparente, e um arquivo HTML de demonstração que roda direto no navegador sem servidor. O link está em baixo. O pacote completo tem cerca de 2,4 MB. As frames são 512x512 pixels cada, 24 frames por ciclo completo de caminhada. Baixar rig do coelho branco (v1.0)
Instalação e configuração inicial
Descompacte o arquivo na pasta do seu projeto. Dentro haverá três subpastas: rig/ (arquivo JSON), frames/ (os PNGs numerados de 001 a 024), e demo/ (o HTML autocontido). Abra demo/index.html no navegador. Você verá o coelho se movendo em loop. Se não aparecer nada, verifique duas coisas:
- O caminho no JSON para a pasta frames/ está relativo ou absoluto. Se você moveu a pasta demo para outro lugar, os caminhos quebram.
- O navegador bloqueou carregamento de arquivos locais. Chrome e Edge bloqueiam XHR de file:// por padrão. Use o flag
--allow-file-access-from-filesou subi o projeto num servidor local simples comnpx serve .
O segundo problema me pegou no início. Passei uma tarde inteira achando que o rig estava corrompido quando na verdade era só o navegador bloqueando as requisições.
Sincronização com áudio
Aqui é onde a coisa fica interessante. O coelho olha para o relógio repetidamente -- esse é o gesto icônico. Para sincronizar com áudio, você não quer mapear frame a frame. Você quer detectar onsets no áudio e disparar a animação do relógio nesses pontos. Use a Web Audio API. Crie um AnalyserNode, extraia os picos de energia, e mapeie cada onset para um índice de frame da animação do relógio. O código base é:
👉 Clique no botão abaixo para saber mais sobre o assunto!
const analyser = ctx.createAnalyser();\nanalyser.fftSize = 2048;\nconst buffer = new Float32Array(analyser.frequencyBinCount);\nanalyser.getFloatTimeDomainData(buffer); Depois de capturar o buffer, calcule a energia RMS por janela de 20ms. Quando o RMS ultrapassar um limiar que você define -- algo em torno de 0,03 para voz normal ou 0,05 para fala alta -- dispare a transição para a frame do relógio levantado. O limiar exato depende do seu áudio de entrada, então faça um teste rápido com 3 segundos de fala antes de ajustar.
Problema de borda que eu encontrei
Num projeto real, tentei sincronizar o coelho com um arquivo de áudio de narração em português. O problema era que a detecção de onsets capturava até consoantes surdas (like "t" e "k") como eventos válidos, fazendo o coelho piscar o relógio a cada sílaba. A solução foi adicionar um deadzone de 150ms entre disparos -- ou seja, após um onset detectado, o sistema ignora novos onsets por 150ms. Isso elimina a maioria das falsas detecções em fala normal sem prejudicar a sincronização geral. O resultado ficou com delay perceptível de cerca de 80ms em relação ao áudio original, o que para animação de personagem é aceitável.
Personalização visual
O sprite em preto e branco padrão pode não combinar com o design do seu projeto. Você pode re-colorir usando dois métodos: Método 1 -- CSS filter: Aplique filter: sepia() saturate() hue-rotate() no elemento canvas. Rápido, sem modificar os arquivos, mas o controle é limitado. Não dá para mudar a cor de uma única peça do desenho.
Método 2 -- Canvas pixel manipulation: Carregue cada frame, itere os pixels via getImageData, e troque a paleta. Isso permite trocar, por exemplo, o colete azul por verde mantendo o restante inalterado. O processamento é pesado -- cada frame leva cerca de 12ms para reprocessar em um notebook médio -- então faça isso apenas na inicialização e cacheie o resultado. Eu usei o método 2 num projeto de livro infantil interativo. A criança podia escolher a cor do coelho antes de começar a leitura. O cacheamento dos frames processados reduziu o tempo de troca de cor de 300ms para menos de 5ms na segunda vez.
Limitações conhecidas
O rig atual suporta quatro movimentos: caminhada, parada, olhar para o relógio, e susto (quando o coelho corre fora do quadro). Não há movimento de fala -- a boca é estática nos sprites. Se o seu projeto exige sincronia labial, você vai precisar adicionar um sprite set separado ou usar uma biblioteca de lip-sync como a Audio2Face, o que complica bastante o setup. Também note que o sprite em 512x512 começa a perder qualidade abaixo de 200px de largura na tela. Se você precisa de versão pequena para mobile, gere um spritesheet separado em 256x256. A diferença de nitidez é perceptível mas aceitável para telas pequenas.
O rig foi desenvolvido para canvas 2D. Se você pretende usar WebGL ou Three.js, precisará converter os sprites em texturas e recriar o sistema de rig como esquelético -- o que é trabalho equivalente a refazer o projeto do zero, não uma simples conversão.
Resumo rápido do que funciona
Rig separado em dois grupos articulares (corpo + membros/acessórios). Onset detection com deadzone de 150ms. Cache de frames processados. Limiar de energia RMS entre 0,03 e 0,05 para voz. Servidor local para evitar bloqueios do navegador. Nada disso é difícil, mas cada etapa tem uma armadilha específica que leva tempo para descobrir. Se tiver alguma dúvida sobre sincronização com áudio ou personalização de paleta, deixe nos comentários. Eu respondo quando consigo.