Animação

Sistema de animação avançado para criar animações dinâmicas, procedurais e baseadas em expressões além de simples quadros-chave.

Tipos de Animação

O sistema de animação suporta vários tipos além dos quadros-chave tradicionais:

  • Expressão: Expressões JavaScript avaliadas por quadro
  • Procedural: Padrões de animação procedural integrados
  • Sequência: Animações sequenciais baseadas em etapas
  • Caminho: Movimento ao longo de caminhos Bezier

Essas animações avançadas são definidas na propriedade de array animations dos elementos.

Animações de Nó vs Quadros-Chave

Animações de Nó (animations array):

  • Animações procedurais, baseadas em expressões ou seguindo caminhos
  • Avaliadas a cada quadro
  • Maior prioridade do que quadros-chave
  • Podem substituir valores de quadros-chave

Quadros-Chave (keyframes array):

  • Interpolação simples de propriedades entre pontos definidos
  • Menor prioridade
  • Previsível, fácil de editar

Prioridade da Animação

Quando vários métodos de animação visam a mesma propriedade:

  1. Mais Alto: Animações de nó (expressão, procedural, caminho, sequência)
  2. Médio: Animações de quadros-chave
  3. Mais Baixo: Valores de propriedades estáticas
PropriedadeTipoNecessárioExemploFaixa de ValoresDescrição
typestringtrue-expression | procedural | sequence | pathO tipo de animação.
enabledbooleanfalse--Se a animação está ativa.
targetstringtrue--O caminho da propriedade a animar (ex: "x", "rotation", "scaleX").
startTimenumberfalse--Hora de início da animação relativa ao início do elemento, em segundos.
durationnumberfalse--Duração da animação em segundos. Para animações em loop, este é o período do loop.
loopbooleanfalse--Se a animação faz loop.
blendModestringfalse-replace | add | multiplyComo esta animação se combina com outras: substituir (sobrescrever), adicionar (soma), multiplicar (escala).
blendWeightnumberfalse--A força/influência desta animação (0-1). Usado para misturar múltiplas animações.

Animações de Expressão

Expressões são códigos JavaScript avaliados por quadro, com acesso a variáveis de contexto de animação.

Variáveis de Contexto Disponíveis

{
  time: number; // Tempo absoluto atual (segundos)
  localTime: number; // Tempo relativo ao início do elemento
  duration: number; // Duração do elemento
  progress: number; // Progresso normalizado (0-1)
  index: number; // Índice do elemento no grupo
  total: number; // Total de elementos no grupo
  fps: number; // Quadros por segundo
  width: number; // Largura do canvas
  height: number; // Altura do canvas
  value: any; // Valor atual da propriedade
}

Exemplo de Expressão

Animação de salto usando funções Math:

expressionAnimation.json
{
"id": "element-1",
"type": "Image",
"start": 0,
"duration": 5,
"animations": [
  {
    "type": "expression",
    "target": "y",
    "enabled": true,
    "expression": "100 + Math.abs(Math.sin(localTime * 3)) * 200",
    "startTime": 0,
    "duration": 5,
    "loop": true
  }
]
}

Expressão Complexa

Combine múltiplos efeitos:

complexExpression.json
{
"animations": [
  {
    "type": "expression",
    "target": "rotation",
    "expression": "(localTime * 2 * Math.PI / duration) + Math.sin(localTime * 4) * 0.1",
    "loop": true
  },
  {
    "type": "expression",
    "target": "scaleX",
    "expression": "1 + Math.sin(localTime * 5) * 0.2",
    "loop": true
  }
]
}

Animações Procedurais

Padrões de animação integrados com parâmetros configuráveis.

Tipos Procedurais

  • wiggle: Oscilação aleatória (útil para efeitos de câmera na mão)
  • wave: Movimento de onda seno/cosseno
  • bounce: Efeito de salto elástico
  • pulse: Escala rítmica

Exemplo de Wiggle

wiggleAnimation.json
{
"animations": [
  {
    "type": "procedural",
    "proceduralType": "wiggle",
    "target": "rotation",
    "enabled": true,
    "frequency": 2,
    "amplitude": 0.1,
    "loop": true
  }
]
}

Animações de Sequência

Animações baseadas em etapas que mudam valores em intervalos específicos.

PropriedadeTipoNecessárioExemploFaixa de ValoresDescrição
valuesarraytrue--Array de valores para percorrer.
stepDurationnumbertrue--Duração de cada etapa em segundos.
loopbooleanfalse--Se deve repetir a sequência.

Exemplo de Sequência

Texto alternando entre tamanhos diferentes:

sequenceAnimation.json
{
"animations": [
  {
    "type": "sequence",
    "target": "fontSize",
    "enabled": true,
    "values": [24, 32, 40, 32, 24],
    "stepDuration": 0.5,
    "loop": true
  }
]
}

Animações de Caminho

Anime elementos ao longo de caminhos de curvas Bezier.

PropriedadeTipoNecessárioExemploFaixa de ValoresDescrição
pathstring | arraytrue--Dados do caminho SVG (atributo d) ou array de pontos do caminho.
autoRotatebooleanfalse--Se deve rotacionar automaticamente o elemento para seguir a tangente do caminho.
durationnumbertrue--Tempo para completar todo o caminho.

Exemplo de Caminho

Movimento circular:

pathAnimation.json
{
"animations": [
  {
    "type": "path",
    "target": "position",
    "enabled": true,
    "path": "M 100,100 a 200,200 0 1,1 0,1 Z",
    "autoRotate": true,
    "duration": 4,
    "loop": true
  }
]
}

Sintaxe do Caminho da Propriedade

A propriedade target utiliza notação de ponto para especificar propriedades aninhadas:

  • Simples: "x", "y", "rotation"
  • Aninhado: "scale.x", "position.y"
  • Array: "colors[0]", "points[2].x"

Exemplos de Resolução de Destino

{
  "target": "x"              // Posição x do elemento
  "target": "scaleX"         // Escala horizontal
  "target": "alpha"          // Opacidade
  "target": "fill.color"     // Cor de preenchimento (se o preenchimento for um objeto)
  "target": "points[0].x"    // Coordenada x do primeiro ponto
}

Modos de Mistura

Controle como as animações se combinam quando várias visam a mesma propriedade:

Substituir (Padrão)

{
  "blendMode": "replace",
  "blendWeight": 1.0
}

Substitui completamente o valor da propriedade.

Adicionar

{
  "blendMode": "add",
  "blendWeight": 0.5
}

Adiciona ao valor existente (ponderado). Útil para acumular deslocamentos.

Multiplicar

{
  "blendMode": "multiply",
  "blendWeight": 1.0
}

Multiplica o valor existente. Útil para efeitos de escala.

Exemplo de Múltiplas Animações

Combinando diferentes tipos de animação:

multipleAnimations.json
{
"id": "animated-element",
"type": "Shape",
"animations": [
  {
    "type": "expression",
    "target": "x",
    "expression": "width / 2 + Math.sin(localTime * 2) * 300",
    "blendMode": "replace",
    "loop": true
  },
  {
    "type": "procedural",
    "proceduralType": "wiggle",
    "target": "rotation",
    "frequency": 3,
    "amplitude": 0.2,
    "blendMode": "add",
    "blendWeight": 0.5
  },
  {
    "type": "sequence",
    "target": "alpha",
    "values": [1, 0.8, 1],
    "stepDuration": 0.3,
    "loop": true,
    "blendMode": "multiply"
  }
],
"keyframes": [
  {
    "id": "kf-1",
    "time": 0,
    "stateObj": { "scaleX": 1 }
  },
  {
    "id": "kf-2",
    "time": 2,
    "stateObj": { "scaleX": 1.5 }
  }
]
}

Neste exemplo:

  • A expressão controla a posição horizontal (modo de substituição)
  • O wiggle procedural adiciona uma variação sutil de rotação
  • A sequência pulsa a opacidade
  • O quadro-chave escala o elemento (prioridade mais baixa)

Notas Importantes

Sandbox de Expressão

  • As expressões são executadas em um contexto restrito por segurança
  • Acesso apenas a variáveis de contexto de animação
  • Não pode acessar DOM, bibliotecas externas ou APIs do Node.js
  • Erros de avaliação desabilitarão a animação

Desempenho

  • Expressões: Avaliadas a cada quadro - mantenha-as simples
  • Procedural: Funções integradas otimizadas - muito eficientes
  • Sequência: Sobrecarga mínima, boa para mudanças discretas
  • Caminho: Custo moderado, depende da complexidade do caminho

Cronometragem

  • startTime e duration são relativos ao tempo de start do elemento
  • localTime em expressões começa em 0 quando o elemento inicia
  • Animações respeitam o limite de duration geral do elemento

Depuração

  • Se uma animação não funcionar, verifique:
    • enabled: true
    • Propriedade target existe no elemento
    • A sintaxe da expressão é JavaScript válido
    • startTime está dentro da duração do elemento
    • Sem erros de digitação no caminho da propriedade

Casos de Uso Comuns

Efeito de Seguimento Suave

{
  "type": "expression",
  "target": "x",
  "expression": "value + (targetX - value) * 0.1"
}

Salto Elástico

{
  "type": "expression",
  "target": "scaleY",
  "expression": "1 + Math.exp(-localTime * 3) * Math.cos(localTime * 8) * 0.5"
}

Tremor de Câmera

{
  "type": "procedural",
  "proceduralType": "wiggle",
  "target": "x",
  "frequency": 10,
  "amplitude": 5
}

Animação Escalonada (em grupos)

{
  "type": "expression",
  "target": "alpha",
  "expression": "Math.max(0, Math.min(1, (localTime - index * 0.1) * 2))"
}