AMP

amp-animation

Define y ejecuta animaciones.

Secuencia de comandos obligatoria <script async custom-element="amp-animation" src="https://cdn.ampproject.org/v0/amp-animation-0.1.js"></script>
Diseños admitidos nodisplay
Ejemplos animations.amp.html

Descripción general

Las animaciones de AMP se basan en la API de Web Animations para definir y ejecutar animaciones en documentos de AMP.

Formato

Los elementos amp-animation definen las animaciones como una estructura JSON.

Especificación de la animación de nivel superior

El objeto de nivel superior define un proceso de animación que consta de un número arbitrario de componentes de animación definidos como una matriz animations:

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

Ubicación en DOM

<amp-animation> solo se puede colocar como elemento secundario directo del elemento <body> si se cumple que trigger="visibility". Se puede colocar en cualquier parte del DOM si no se define trigger y la reproducción de la animación se controla de forma automática a través de sus acciones.

Componentes de animación

Cada componente de la animación es un efecto de fotogramas clave (keyframe effect) compuesto por:

  • Elementos "target", a los que se hace referencia mediante un selector
  • Condiciones: media query y condición "supports"
  • Propiedades de tiempo
  • Fotogramas clave
{
  "selector": "#target-id",
  // Conditions
  // Variables
  // Timing properties
  // Subtargets
  ...
  "keyframes": []
}

Condiciones

Las condiciones pueden definir si este componente de animación se incluye en la animación final.

Media query

La media query se puede especificar mediante la propiedad media, que puede contener cualquier expresión permitida de la API de Window.matchMedia, y que se corresponde con la regla de CSS @media.

Si se define un valor de un componente de animación, dicho componente solo se incluirá si la media query coincide con el entorno actual.

Condición "supports"

Esta condición se puede especificar utilizando la propiedad supports. Puede contener cualquier expresión permitida para el API de CSS.supports y se corresponde con la regla de CSS @supports.

Si se define un valor de un componente de animación, dicho componente solo se incluirá si la condición "supports" coincide con el entorno actual.

Instrucción de animación switch

En algunos casos, es conveniente combinar en una única animación varias animaciones condicionales con un valor predeterminado opcional. Esto se puede hacer mediante la declaración de animación switch, siguiendo este formato:

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

En la animación switch, los candidatos se evalúan en el orden definido y se ejecuta la primera animación que coincida con las declaraciones condicionales, mientras que el resto se ignoran.

Por ejemplo, esta animación ejecuta la animación de trayectoria de movimiento si se admite; de lo contrario, utiliza la propiedad "transform" como respaldo:

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

Variables

Los componentes de animación pueden declarar variables de CSS que se utilizarán para los valores de tiempo y de fotogramas clave mediante las expresiones var(), ``que se evalúan mediante el contexto actual del target. Las variables de CSS especificadas en los componentes de animación se propagan a animaciones anidadas y se aplican a los targets de animación. Como consecuencia, estas serán las que se utilicen en las animaciones finales.

Por ejemplo:

<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>

En este ejemplo:

  • --delay se propaga a las animaciones anidadas y se utiliza como retraso de la animación de #target1.
  • --x se propaga a las animaciones anidadas, pero se anula mediante la animación #target1 y se utiliza posteriormente para la propiedad transform.
  • --y no se ha especificado en ninguna parte de <amp-animation> y, por lo tanto, se consultará en el elemento #target1. Si no se define en CSS, el valor predeterminado es 0px.

Para obtener más información sobre var(), consulta la sección sobre var() y calc().

Propiedades de tiempo

Los componentes de animación y animación de nivel superior pueden contener propiedades de tiempo, las cuales se definen detalladamente en el diccionario de AnimationEffectTimingProperties de la especificación de Web Animation. El conjunto de propiedades permitidas incluye:

Propiedad Tipo Valor predeterminado Descripción
duration hora 0 Duración de la animación. Puede ser un valor numérico en milisegundos o un valor de tiempo de CSS, como 2s.
delay hora 0 Retraso antes de que la animación comience a ejecutarse. Puede ser un valor numérico en milisegundos o un valor de tiempo de CSS, como 2s.
endDelay hora 0 Tiempo posterior a la finalización de la animación que tiene que transcurrir para que se considere del todo finalizada. Puede ser un valor numérico en milisegundos o un valor de tiempo de CSS, como 2s.
iterations número o
"Infinity" o
"infinite"
1 Número de veces que se repite el efecto de animación.
iterationStart número o CSS 0 Compensación horaria tras la cual se activa el efecto de animación.
easing cadena "linear" Función de tiempo que se utiliza para modificar el transcurso del tiempo para producir efectos de easing.
direction cadena "normal" Uno de los siguientes valores: "normal", "reverse", "alternate" o "alternate-reverse".
fill cadena "none" Uno de los siguientes valores: "none", "forwards", "backwards", "both" o "auto".

Todas las propiedades de tiempo admiten valores numéricos o de cadena directos, así como de CSS. Por ejemplo, "duration" se puede definir como 1000, 1s o 1000ms. Además, también se admiten las expresiones calc(), var() y otras expresiones de CSS.

Ejemplo de propiedades de tiempo en JSON:

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

Los componentes de animación heredan las propiedades de tiempo especificadas para la animación de nivel superior.

Subtargets

En cualquier lugar donde se pueda especificar selector, también es posible especificar subtargets: []. Los subtargets pueden anular las propiedades de tiempo o las variables que se definen en la animación de subtargets específicos indicados mediante un índice o un selector de CSS.

Por ejemplo:

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

En este ejemplo, todos los targets que coincidan con ".target" tendrán de forma predeterminada un retraso de 100 ms y un "--y" de 100 píxeles. Sin embargo, se anula el primer target (index: 0) para tener 200 ms de retraso, y los targets impares se anulan para tener un "--y" de 200 píxeles.

Ten en cuenta que varios subtargets pueden coincidir con un target.

Fotogramas clave (keyframes)

Los fotogramas clave se pueden especificar de las formas que se describen en la sección de fotogramas clave de la especificación de Web Animations o como una cadena que haga referencia al nombre @keyframes en el CSS.

A continuación, se muestran algunos ejemplos típicos de definiciones de fotogramas clave.

El formato abreviado de notación de objeto "to" define el estado final en 100 %:

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

El formato abreviado de notación de objeto "from-to" define los estados inicial y final en 0 y 100 %:

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

El formato abreviado de notación de objeto "value-array" define varios valores para las compensaciones de estado inicial, de estado final y múltiples (con espaciado equidistante):

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

El formato de notación de matriz define los fotogramas clave. Las compensaciones se asignan automáticamente a 0, 100 % y con espaciado equidistante:

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

El formato de notación de matriz también puede incluir" "offset" (compensación) de forma explícita:

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

El formato de notación de matriz también puede incluir "easing":

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

Para obtener más información sobre los formatos de fotogramas clave, consulta la especificación de Web Animations.

Los valores de propiedad admiten cualquier valor de CSS válido, como calc(), var() y otras expresiones.

Fotogramas clave de CSS

Los fotogramas clave también se pueden especificar en la hoja de estilo del documento (etiqueta <style>) como reglas de CSS @keyframes. Por ejemplo:

<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>

Los @keyframes de CSS son, en su mayoría, equivalentes a la definición de fotogramas clave insertados del JSON, tal y como se describe en la especificación de Web Animations. Sin embargo, hay algunos matices:

  • Para lograr la compatibilidad con una amplia variedad de plataformas, pueden ser necesarios los prefijos de proveedor, como @-ms-keyframes {} o -moz-transform. No son necesarios y no se admiten en el formato JSON, pero podrían requerirse en CSS.
  • Las plataformas que no admiten calc() y var() no podrán aprovechar las ventajas de los polyfills de amp-animation cuando se especifiquen los fotogramas clave en CSS. Por lo tanto, se recomienda incluir siempre valores de respaldo en CSS.
  • No se pueden utilizar las extensiones de CSS como width(), height(), num(), rand(), index() y length().

Propiedades de fotogramas clave incluidas en la lista blanca

No se pueden utilizar todas las propiedades de CSS en los fotogramas clave, ya que solo aparecen en la lista blanca las que los navegadores modernos pueden optimizar y animar rápidamente. Esta lista aumentará a medida que se confirme el buen rendimiento de otras propiedades. Por ahora, la lista incluye: - opacity - transform - visibility - offset-distance

Ten en cuenta que el uso de propiedades de CSS con prefijo de proveedor no es necesario ni está permitido.

Formas abreviadas de la configuración de animación

Si la animación se compone de un único elemento y solo hace falta un efecto de fotogramas clave, la configuración se puede limitar a este componente de animación. Por ejemplo:

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

Si la animación está formada por una lista de componentes, pero no tiene una animación de nivel superior, la configuración se puede limitar a una matriz de componentes. Por ejemplo:

  <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>

Composición de la animación

Las animaciones pueden hacer referencia a otras animaciones, combinando así varias declaraciones amp-animation en una única animación final. Este procedimiento es parecido a la anidación. Separar las animaciones en diferentes elementos tiene la ventaja de poder reutilizar la misma animación en varios lugares o de hacer que cada declaración de animación sea más pequeña y fácil de gestionar.

Por ejemplo:

<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>

En este ejemplo, se incluye la animación "anim2" como parte de "anim1". "anim2" se incluye sin un target (selector). En ese caso, la intención es que la animación incluida haga referencia a su propio target.

Otro procedimiento permite que la animación incluida proporcione uno o varios targets. En ese caso, la animación incluida se ejecuta para cada target que coincida. Por ejemplo:

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

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

En este caso, tanto si ".target-class" coincide con un elemento, con varios o con ninguno, "anim2" se ejecuta para cada target con el que coincida.

Las variables y las propiedades de tiempo especificadas en la animación de llamada también se transmiten a la animación incluida.

Expresiones var() y calc()

amp-animation permite el uso de las expresiones var() y calc() para los valores de tiempo y los fotogramas clave.

Por ejemplo:

<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>

Tanto var() como calc() añaden un polyfill en las plataformas que no las admiten directamente. Las propiedades de var() se extraen de los elementos target correspondientes. Sin embargo, es imposible proporcionar un polyfill completo para var(). Por lo tanto, si la compatibilidad es importante, se recomienda encarecidamente incluir valores predeterminados en las expresiones var(). Por ejemplo:

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

Los componentes de animación pueden definir sus propias variables como campos --var-name. Estas variables se propagan a las animaciones anidadas y anulan las variables de los elementos target especificados en la hoja de estilo (etiqueta <style>). Las expresiones var() intentan en primer lugar resolver los valores de las variables definidas en las animaciones y, a continuación, consultan los estilos target.

Extensiones de CSS

amp-animation proporciona varias extensiones de CSS para las necesidades típicas de las animaciones: rand(), num(), width() y height(). Estas funciones se pueden utilizar en los lugares que admiten valores de CSS dentro de amp-animation, incluidos los valores de tiempo y de fotogramas clave.

Extensión index() de CSS

La función index() devuelve un índice del elemento target actual del efecto de animación. Es especialmente útil cuando se utilizan varios targets animados con el mismo efecto mediante la propiedad selector. El primer target que coincida con el selector tendrá el índice 0 , el segundo tendrá el índice 1 y así sucesivamente.

Entre otras cosas, esta propiedad se puede combinar con expresiones calc() y utilizar para crear un efecto escalonado. Por ejemplo:

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

Extensión length() de CSS

La función length() devuelve el número de elementos target incluidos en el efecto de animación. Es más útil cuando se combina con index():

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

Extensión rand() de CSS

La función rand() devuelve un valor de CSS aleatorio. Se puede utilizar de dos maneras:

La primera no incluye argumentos, y devuelve simplemente un número aleatorio entre 0 y 1.

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

La segunda incluye dos argumentos, y devuelve un valor aleatorio que se encuentra entre ellos.

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

Extensiones width() y height() de CSS

Las extensiones width() y height() devuelven respectivamente la anchura y la altura del elemento animado o del elemento que especifica el selector, en píxeles (p. ej., 100px).

Se admiten los siguientes formatos:

  • width() y height(): anchura o altura del elemento animado.
  • width('.selector') y height('.selector'): anchura o altura del elemento que especifica el selector. Se puede utilizar cualquier selector de CSS, como width('#container &gt; li').
  • width(closest('.selector')) y height(closest('.selector')): anchura o altura del elemento que especifica el selector más cercano.

width() y height() son especialmente útiles para las transformaciones. Las propiedades de CSS como left y top que pueden utilizar valores con % para definir las proporciones de las animaciones respecto al tamaño del contenedor. Sin embargo, la propiedad transform interpreta los valores % de forma diferente: como un porcentaje del elemento seleccionado. Por lo tanto, width() y height() se pueden utilizar para definir transformaciones en las animaciones en lo que respecta a elementos contenedores u otros similares.

Estas funciones se pueden combinar con calc(), var() y otras expresiones de CSS. Por ejemplo:

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

Extensión num() de CSS

La función num() devuelve una representación numérica de un valor de CSS. Por ejemplo:

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

Por ejemplo, la siguiente expresión calcula el retraso en segundos proporcional a la anchura del elemento:

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

Animaciones SVG

El formato SVG es excelente y, por ello, recomendamos su uso en las animaciones.

Las animaciones con SVG se basan en las mismas propiedades de CSS que se describen en la sección Propiedades de fotogramas clave incluidas en la lista blanca, con algunos matices:

  • Los elementos SVG de IE y Edge no son compatibles con el CSS de las propiedades transform. La propia animación de transform utiliza un polyfill. Sin embargo, no se aplica el estado inicial definido en una hoja de estilo. Si el estado de transformación inicial es importante para IE o Edge, se recomienda duplicarlo mediante el atributo transform de SVG.
  • Aunque se incluye un polyfill del CSS de transform para IE y Edge, no se puede incluir para transform-origin. Por lo tanto, cuando se quiera lograr la compatibilidad con IE o Edge, se recomienda utilizar únicamente la forma predeterminada de transform-origin.
  • Actualmente, la mayoría de los navegadores tienen problemas para interpretar correctamente el CSS de transform-origin. Para obtener más información, consulta los problemas habituales en Chrome, Safari y Firefox. La mayor parte de esta confusión se debería solucionar una vez que se implemente el CSS de transform-box. Si transform-origin tiene importancia, se recomienda incluir también el CSS de transform-box que se necesite, por cuestiones de compatibilidad futura.

Activar la animación

La animación se puede activar mediante un atributo trigger o una acción on.

Atributo trigger

Actualmente, visibility es el único valor disponible para el atributo trigger. visibility se activa cuando el documento o la inserción subyacente están visibles en el viewport.

Por ejemplo:

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

Activar mediante la acción on

Por ejemplo:

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

Acciones de on

El elemento amp-animation exporta las siguientes acciones:

  • start: inicia la animación si aún no se está ejecutando. Las propiedades y las variables de tiempo se pueden especificar como argumentos de acción; por ejemplo, anim1.start(delay=-100, --scale=2).
  • restart: inicia la animación o reinicia la que se está ejecutando. Las propiedades y las variables de tiempo se pueden especificar como argumentos de acción; por ejemplo, anim1.start(delay=-100, --scale=2).
  • pause: pausa la animación que se está ejecutando.
  • resume: reactiva la animación que se está ejecutando.
  • togglePause: alterna entre las acciones de pausa y reactivación.
  • seekTo: detiene la animación y busca el momento especificado por el argumento time en milisegundos o por el argumento percent como un punto porcentual en la línea de tiempo.
  • reverse: invierte la animación.
  • finish: finaliza la animación.
  • cancel: cancela la animación.
¿Necesitas más ayuda?

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