AMP

amp-animation

Define e executa animações.

Script obrigatório <script async custom-element="amp-animation" src="https://cdn.ampproject.org/v0/amp-animation-0.1.js"></script>
Layouts compatíveis nodisplay
Exemplos animations.amp.html

Visão geral

O AMP Animations usa a API Web Animations (link em inglês) para definir e executar animações em documentos AMP.

Formato

Um elemento amp-animation define a animação como uma estrutura JSON.

Especificação de animação de nível superior

O objeto de nível superior define um processo geral de animação, que consiste em um número arbitrário de componentes de animação definidos como uma matriz animations:

<amp-animation layout="nodisplay">
<script type="application/json">
{
  // Timing properties
  ...
  "animations": [
    {
      // Animation 1
    },
    ...
    {
      // Animation N
    }
  ]
}
</script>
</amp-animation>

Posicionamento no DOM

<amp-animation> só pode ser colocado como filho direto do elemento <body> se trigger="visibility". Se o trigger não for especificado e a reprodução da animação for controlada de modo programático por meio das ações dela, ele poderá ser posicionado em qualquer lugar no DOM.

Componente de animação

Cada componente de animação tem um efeito de frame-chave (link em inglês) e é composto por:

  • elementos desejados referenciados por um seletor;
  • condições (consulta de mídia e condição de suporte);
  • propriedades de tempo;
  • frames-chave.
{
  "selector": "#target-id",
  // Conditions
  // Variables
  // Timing properties
  // Subtargets
  ...
  "keyframes": []
}

Condições

As condições podem especificar se o componente de animação será incluído na animação final.

Consulta de mídia

A consulta de mídia pode ser especificada usando a propriedade media. Essa propriedade pode conter qualquer expressão permitida para a API Window.matchMedia e corresponde à regra CSS @media.

Se um valor for especificado para um componente de animação, o componente só será incluído se a consulta de mídia corresponder ao ambiente atual.

Condição de suporte

A condição de suporte pode ser especificada usando a propriedade supports. Essa propriedade pode conter qualquer expressão permitida para a API CSS.supports e corresponde à regra CSS @supports.

Se um valor for especificado para um componente de animação, o componente só será incluído se a condição de suporte corresponder ao ambiente atual.

Declaração de animação switch

Em alguns casos, é recomendável combinar várias animações condicionais com um padrão opcional em uma única animação. Isso pode ser feito usando a declaração de animação switch neste formato:

{
  // Optional selector, vars, timing
  ...
  "switch": [
    {
      "media": "(min-width: 320px)",
      "keyframes": {...},
    },
    {
      "supports": "offset-distance: 0",
      "keyframes": {...},
    },
    {
      // Optional default: no conditionals
    }
  ]
}

Na animação switch, os candidatos são avaliados na ordem definida, e a primeira animação que corresponda às declarações condicionais é executada, enquanto o restante é ignorado.

Por exemplo, esta animação executa uma animação com trajetória, se compatível, e volta para transformar:

{
  "selector": "#target1",
  "duration": "1s",
  "switch": [
    {
      "supports": "offset-distance: 0",
      "keyframes": {
        "offsetDistance": [0, '300px']
      }
    },
    {
      "keyframes": {
        "transform": [0, '300px']
      }
    }
  ]
}

Variáveis

Um componente de animação pode declarar variáveis CSS que serão usadas para valores de tempo e de frames-chave por meio de expressões var(). As expressões var() são avaliadas usando o contexto de destino atual. As variáveis CSS especificadas nos componentes de animação são propagadas para animações aninhadas, aplicadas a destinos de animação e, assim, substituem as variáveis CSS usadas nas animações finais.

Por exemplo:

<amp-animation layout="nodisplay">
<script type="application/json">
{
  "--delay": "0.5s",
  "--x": "100px",
  "animations": [
    {
      "selector": "#target1",
      "delay": "var(--delay)",
      "--x": "150px",
      "keyframes": {"transform": "translate(var(--x), var(--y, 0px)"}
    },
    ...
  ]
}
</script>
</amp-animation>

Neste exemplo:

--delay é propagado para animações aninhadas e usado como um atraso da animação #target1. - --x é propagado para animações aninhadas, mas substituído pela animação #target1 e depois usado para a propriedade transform. - --y não é especificado em nenhum lugar do <amp-animation> e, portanto, será consultado no elemento #target1. O padrão será 0px se não for definido no CSS.

Para mais informações sobre var(), consulte a seção var() e calc().

Propriedades de tempo

Os componentes de animação e de animação de nível superior podem conter propriedades de tempo. Essas propriedades são definidas em detalhes no AnimationEffectTimingProperties (link em inglês) da especificação da Web Animation. O conjunto de propriedades permitidas inclui:

Propriedade Tipo Padrão Descrição
duration tempo 0 A duração da animação. Um valor numérico em milissegundos ou um valor de tempo CSS, por exemplo, 2s.
delay tempo 0 O atraso antes da execução da animação. Um valor numérico em milissegundos ou um valor de tempo CSS, por exemplo, 2s.
endDelay tempo 0 O atraso após a conclusão da animação e antes de ela ser considerada realmente concluída. Um valor numérico em milissegundos ou um valor de tempo CSS, por exemplo, 2s.
iterations número ou
"Infinity" ou
"infinite"
1 O número de vezes que o efeito de animação se repete.
iterationStart número/CSS 0 O ajuste de horário em que o efeito começa a ficar animado.
easing string "linear" A função de tempo (link em inglês) usada para dimensionar o tempo para produzir efeitos de easing.
direction string "normal" "normal", "reverse", "alternate" ou "alternate-reverse".
fill string "none" "none", "forwards", "backwards", "both" ou "auto".

Todas as propriedades de tempo permitem valores diretos numéricos/de strings ou valores CSS. Por exemplo, "duration" pode ser especificado como 1000, 1s ou 1000ms. Além disso, calc() e var() e outras expressões CSS também são permitidas.

Um exemplo de propriedades de tempo em JSON:

{
  ...
  "duration": "1s",
  "delay": 100,
  "endDelay": "var(--end-delay, 10ms)",
  "easing": "ease-in",
  "fill": "both"
  ...
  }

Os componentes de animação herdam as propriedades de tempo especificadas para a animação de nível superior.

Subdestinos

Em todos os locais em que o selector pode ser especificado, também é possível especificar subtargets: []. Os subdestinos podem modificar as propriedades de tempo ou variáveis definidas na animação para subdestinos específicos, indicados por meio de um seletor de CSS ou um índice.

Por exemplo:

  "selector": ".target",
  "delay": 100,
  "--y": "100px",
  "subtargets": [
    {
      "index": 0,
      "delay": 200,
    },
    {
      "selector": ":nth-child(2n+1)",
      "--y": "200px"
    }
  ]
}

Nesse exemplo, por padrão, todos os destinos correspondentes a ".target" têm um atraso de 100 ms e "--y" "de 100 px. No entanto, o primeiro destino (index: 0) é modificado para ter um atraso de 200 ms, e os destinos ímpares são modificados para terem "--y" de 200 px.

Observe que vários subdestinos podem corresponder a um único elemento de destino.

Frames-chave

Os frames-chave podem ser especificados de várias maneiras, descritas na seção de frames-chave da especificação da API Web Animations ou como uma string que se refere ao nome dos @keyframes no CSS.

Veja abaixo alguns exemplos típicos de definições de frames-chave.

O formato de objeto abreviado "to" especifica o estado final em 100%:

{
  "keyframes": {"opacity": 0, "transform": "scale(2)"}
}

O formato de objeto abreviado "from-to" especifica os estados inicial e final, em 0% e 100%:

{
  "keyframes": {
    "opacity": [1, 0],
  "transform": ["scale(1)", "scale(2)"]
}
}

O formato de objeto abreviado "value-array" especifica vários valores para os estados inicial e final e para vários ajustes (com espaços iguais):

{
  "keyframes": {
    "opacity": [1, 0.1, 0],
    "transform": ["scale(1)", "scale(1.1)", "scale(2)"]
}
}

O formato de matriz especifica os frames-chave. Os ajustes são atribuídos automaticamente a 0, 100% e espaçados de maneira uniforme entre si:

{
  "keyframes": [
    {"opacity": 1, "transform": "scale(1)"},
  {"opacity": 0, "transform": "scale(2)"}
]
}

O formato de matriz também pode incluir o "offset" de modo explícito:

{
  "keyframes": [
    {"opacity": 1, "transform": "scale(1)"},
  {"offset": 0.1, "opacity": 0.1, "transform": "scale(2)"},
{"opacity": 0, "transform": "scale(3)"}
]
}

O formato de matriz também pode incluir "easing":

{
  "keyframes": [
    {"easing": "ease-out", "opacity": 1, "transform": "scale(1)"},
  {"opacity": 0, "transform": "scale(2)"}
]
}

Para outros formatos de frames-chave, consulte a especificação da Web Animations (link em inglês).

Os valores de propriedades permitem qualquer valor CSS válido, incluindo calc(), var() e outras expressões CSS.

Frames-chave do CSS

Outra maneira de especificar frames-chave é na folha de estilo do documento (tag <style>) como uma regra de @keyframes do CSS. Por exemplo:

<style amp-custom>
  @keyframes keyframes1 {
    from {
      opacity: 0;
    }
    to {
      opacity: 1;
    }
  }
</style>

<amp-animation layout="nodisplay">
<script type="application/json">
{
  "duration": "1s",
  "keyframes": "keyframes1"
}
</script>
</amp-animation>

@keyframes do CSS são equivalentes a aplicar in-line à definição das frames-chave no JSON de acordo com as especificações da Web Animations (link em inglês). No entanto, há algumas nuances:

  • Para compatibilidade com várias plataformas, podem ser necessários prefixos de fornecedor, como @-ms-keyframes {} ou -moz-transform. Os prefixos de fornecedores não são necessários nem permitidos no formato JSON, mas no CSS eles podem ser necessários.
  • As plataformas que não compatíveis com calc() e var() não poderão usar polyfills do amp-animation quando forem especificados frames-chave no CSS. Portanto, é sempre recomendável incluir valores substitutos no CSS.
  • Extensões de CSS, como width(), height(), num(), rand(), index() e length(), não podem ser usadas no CSS.

Propriedades permitidas para frames-chave

Nem todas as propriedades do CSS podem ser usadas em frames-chave. Somente as propriedades CSS que os navegadores modernos podem otimizar e animar de forma rápida são incluídas na lista de permissões. Essa lista aumentará à medida que mais propriedades forem confirmadas como geradoras de bom desempenho. No momento, a lista contém: - opacity - transform - visibility - offset-distance

Observe que o uso de propriedades CSS com prefixos do fornecedor não é necessário nem permitido.

Formas abreviadas de configuração de animação

Se a animação envolver apenas um único elemento, e um único efeito de frames-chave for suficiente, a configuração poderá ser reduzida a esse único componente de animação. Por exemplo:

<amp-animation layout="nodisplay">
<script type="application/json">
{
  "selector": "#target-id",
  "duration": "1s",
  "keyframes": {"opacity": 1}
}
</script>
</amp-animation>

Se a animação for composta por uma lista de componentes, mas não tiver animação de nível superior, a configuração poderá ser reduzida a uma matriz de componentes. Por exemplo:

  <amp-animation layout="nodisplay">
  <script type="application/json">
  [
    {
      "selector": ".target-class",
      "duration": 1000,
      "keyframes": {"opacity": 1}
    },
    {
      "selector": ".target-class",
      "duration": 600,
      "delay": 400,
      "keyframes": {"transform": "scale(2)"}
    }
  ]
  </script>
  </amp-animation>

Composição de animação

As animações podem fazer referência a outras animações, combinando várias declarações de amp-animation em uma única animação final. Fazer referência a uma animação a partir de outra animação é basicamente o mesmo que aninhar. O motivo para dividir animações em elementos diferentes seria reutilizar a mesma animação em vários lugares ou simplesmente tornar cada declaração de animação menor e mais gerenciável.

Por exemplo:

<amp-animation id="anim1" layout="nodisplay">
<script type="application/json">
{
  "animation": "anim2",
  "duration": 1000,
  "--scale": 2
}
</script>
</amp-animation>

<amp-animation id="anim2" layout="nodisplay">
<script type="application/json">
{
  "selector": ".target-class",
  "keyframes": {"transform": "scale(var(--scale))"}
}
</script>
</amp-animation>

Esse exemplo de animação combina a animação "anim2" "como parte de "anim1". "anim2" é incluído sem um destino (selector). Nesse caso, a animação incluída provavelmente fará referência ao próprio destino.

Outro formato permite que a animação incluída forneça um destino ou vários. Nesse caso, a animação incluída é executada para cada destino correspondente. Por exemplo: ```html

Aqui, se "target-class" corresponder a um elemento, vários ou nenhum, o "anim2' será executado para cada destino correspondente.

As variáveis e as propriedades de tempo especificadas na animação de autor da chamada também são transmitidas para a animação incluída.

### Expressões `var()` e `calc()`

O `amp-animation` permite o uso de expressões `var()` e `calc()` para valores de tempo e frames-chave.

Por exemplo:
```html
<amp-animation layout="nodisplay">
<script type="application/json">
[
  {
    "selector": ".target-class",
    "duration": "4s",
    "delay": "var(--delay)",
    "--y": "var(--other-y, 100px)",
    "keyframes": {"transform": "translate(calc(100vh + 20px), var(--y))"}
  }
]
</script>
</amp-animation>

O polyfill é aplicado às expressões var() e calc() em plataformas que não são diretamente compatíveis com elas. As propriedades de var() são extraídas dos elementos de destino correspondentes. No entanto, não é possível aplicar totalmente o polyfill a var(). Assim, quando a compatibilidade for importante, é recomendável incluir valores padrão nas expressões var(). Por exemplo:

  <amp-animation layout="nodisplay">
  <script type="application/json">
  [
    {
      "selector": ".target-class",
      "duration": "4s",
      "delay": "var(--delay, 100ms)",
    }
  ]
  </script>
  </amp-animation>

Os componentes de animação podem especificar as próprias variáveis como campos --var-name. Essas variáveis são propagadas em animações aninhadas e substituem variáveis de elementos de destino especificadas pela folha de estilo (tag <style>). As expressões var() primeiro tentam resolver os valores de variáveis especificados nas animações e depois consultam os estilos de destino.

Extensões CSS

O amp-animation fornece várias extensões CSS para necessidades típicas de animações: rand(), num(), width() e height(). Essas funções podem ser usadas em todos os lugares em que os valores de CSS possam ser utilizados no amp-animation, incluindo valores de tempo e de frames-chave.

Extensão CSS index()

A função index() retorna um índice do elemento de destino atual no efeito de animação. Isso é mais relevante quando vários destinos são animados com o mesmo efeito usando a propriedade selector. O primeiro destino correspondido pelo seletor terá o índice 0, o segundo terá o índice 1 e assim por diante.

Entre outras coisas, essa propriedade pode ser combinada com expressões calc() e ser usada para criar efeito escalonado. Por exemplo:

{
  "selector": ".class-x",
  "delay": "calc(200ms * index())"
  }

Extensão CSS length()

A função length() retorna o número de elementos de destino no efeito de animação. Isso é mais relevante quando combinado com index():

{
  "selector": ".class-x",
  "delay": "calc(200ms * (length() - index()))"
  }

Extensão CSS rand()

A função rand() retorna um valor CSS aleatório. Existem dois formatos.

A forma sem argumentos simplesmente retorna o número aleatório entre 0 e 1.

{
  "delay": "calc(10s * rand())"
  }

O segundo formato tem dois argumentos e retorna o valor aleatório entre eles.

{
  "delay": "rand(5s, 10s)"
  }

Extensões CSS width() e height()

As extensões width() e height() retornam a largura/altura do elemento animado ou o elemento especificado pelo seletor. O valor retornado está em pixels, por exemplo, 100px.

Os seguintes formatos são aceitos:

  • width() e height() - largura/altura do elemento animado.
  • width('.selector') e height('.selector') - largura/altura do elemento especificado pelo seletor. Qualquer seletor de CSS pode ser usado. Por exemplo, width('#container &gt; li').
  • width(closest('.selector')) e height(closest('.selector')) - largura/altura do elemento especificado pelo seletor mais próximo.

width() e height() são especialmente úteis para transformações. As propriedades CSS left, top e semelhantes que podem usar valores em % para expressar animações proporcionais ao tamanho do contêiner. No entanto, a propriedade transform interpreta os valores em % de forma diferente: como uma porcentagem do elemento selecionado. Assim, width() e height() podem ser usados para expressar animações de transformação em termos de elementos de contêiner e similares.

Essas funções podem ser combinadas com calc(), var() e outras expressões CSS. Por exemplo:

{
  "transform": "translateX(calc(width('#container') + 10px))"
  }

Extensão CSS num()

A função num() retorna uma representação numérica de um valor CSS. Por exemplo:

  • num(11px) gera 11
  • num(110ms) gera 110
  • etc.

Por exemplo, a expressão a seguir calcula o atraso em segundos proporcional à largura do elemento:

{
  "delay": "calc(1s * num(width()) / 100)"
  }

Animações SVG

SVGs são incríveis e certamente recomendamos o uso deles em animações.

As animações SVG são compatíveis usando as mesmas propriedades CSS descritas em Propriedades permitidas para frames-chave, com algumas nuances:

  • Os elementos SVG do IE/Edge não são compatíveis com as propriedades CSS transform (link em inglês). A própria animação transform tem polyfill aplicado. No entanto, o estado inicial definido em uma folha de estilo não é aplicado. Se o estado transformado inicial for importante no IE/Edge, é recomendável duplicá-lo por meio do atributo transform do SVG.
  • Embora o CSS transform tenha polyfill aplicado para o IE/Edge, não é possível transformar transform-origin em um polypill. Assim, quando a compatibilidade com o IE/Edge é desejada, recomenda-se usar somente o transform-origin padrão.
  • A maioria dos navegadores atuais tem problemas para interpretar o CSS transform-origin corretamente. Veja os problemas do Chrome, Safari e Firefox. A maior parte dessa confusão provavelmente é resolvida depois que o CSS transform-box é implementado. Quando transform-origin é importante, recomenda-se incluir também o CSS transform-box desejado para compatibilidade futura.

Acionar animação

A animação pode ser acionada por meio do atributo trigger ou da ação on.

Atributo trigger

Atualmente, visibility é o único valor disponível para o atributo trigger. O visibility é acionado quando o documento subjacente ou a incorporação está visível (na janela de visualização).

Por exemplo:

<amp-animation id="anim1" layout="nodisplay"
    trigger="visibility">
    ...
  </amp-animation>

Acionar usando a ação on

Por exemplo:

<amp-animation id="anim1" layout="nodisplay">
  ...
</amp-animation>
<button on="tap:anim1.start">Animate</button>

Ações on

O elemento amp-animation exporta as seguintes ações:

  • start: inicia a animação se ela ainda não estiver sendo executada. As propriedades e variáveis de tempo podem ser especificadas como argumentos de ação. Por exemplo: anim1.start(delay=-100, --scale=2).
  • restart: inicia a animação ou reinicia a animação em execução no momento. As propriedades e variáveis de tempo podem ser especificadas como argumentos de ação. Por exemplo: anim1.start(delay=-100, --scale=2).
  • pause: pausa a animação em execução no momento.
  • resume: retoma a animação em execução no momento.
  • togglePause: alterna entre pausar e retomar ações.
  • seekTo: pausa a animação e busca o ponto de tempo especificado pelo argumento time, em milissegundos, ou no argumento percent, como um ponto da porcentagem na linha do tempo.
  • reverse: reverte a animação.
  • finish: conclui a animação.
  • cancel: cancela a animação.
Precisa de mais ajuda?

You've read this document a dozen times but it doesn't really cover all of your questions? Maybe other people felt the same: reach out to them on Stack Overflow.

Go to Stack Overflow
Found a bug or missing a feature?

The AMP project strongly encourages your participation and contributions! We hope you'll become an ongoing participant in our open source community but we also welcome one-off contributions for the issues you're particularly passionate about.

Go to GitHub