AMP

amp-animation

Определяет и запускает анимацию.

Скрипт
Поддерживаемые макеты nodisplay
Примеры animations.amp.html

Обзор

В документах AMP анимация определяется и выполняется с помощью Web Animations API.

Формат

Элемент amp-animation определяет такую анимацию как структуру JSON.

Спецификация анимации верхнего уровня

Объект верхнего уровня определяет общий процесс анимации, который состоит из произвольного числа ее компонентов, заданных как массив animations:

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

Размещение в DOM

<amp-animation> разрешено размещать как прямой дочерний элемент для <body>, если trigger="visibility". Если trigger не указан и воспроизведение анимации контролируется программно через ее действия, ее можно разместить в любом месте DOM.

Компонент анимации

Каждый компонент анимации является эффектом ключевых кадров и состоит из:

– целевых элементов, на которые ссылается селектор; – условий: запрос медиа и условие supports; – временные свойства; – ключевые кадры.

{
  "selector": "#target-id",
  // Conditions
  // Variables
  // Timing properties
  // Subtargets
  ...
  "keyframes": []
}

Условия

Условия могут определять, включен ли этот компонент в финальную анимацию.

Запрос медиа

Запрос медиа может быть задан с помощью свойства media. Оно может содержать любое выражение, разрешенное для Window.matchMedia API, и соответствует правилу CSS @media.

Если для компонента анимации указано значение, он включается, только если запрос медиа соответствует текущей среде.

Условие supports

Условие supports может быть определено с помощью свойства supports. Оно может содержать любое выражение, разрешенное для Window.matchMedia API, и соответствует правилу CSS @supports.

Если для компонента анимации указано значение, он включается, только если условие supports соответствует текущей среде.

Оператор анимации switch

В некоторых случаях удобно объединять несколько условных анимаций с необязательным значением по умолчанию в одну. Это можно сделать с помощью оператора анимации switch:

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

В анимации switch варианты оцениваются в заданном порядке. Выполняется первая анимация, которая соответствует операторам условий, а остальные игнорируются.

Например, следующий код запускает анимацию движения, если она поддерживается, и возвращается к свойству transform:

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

Переменные

Компонент анимации может декларировать переменные CSS, которые будут использоваться для определения временных рамок и ключевых кадров, с помощью выражений var(). Выражения var() оцениваются по текущему целевому контексту. Переменные CSS, указанные в компонентах анимации, применяются к вложенным анимациям, целям анимации и, таким образом, переопределяют переменные CSS, используемые в конечных анимациях.

Пример:

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

В этом примере

--delay добавляется во вложенные анимации и применяется как задержка анимации #target1, --x добавляется во вложенные анимации, но переопределяется анимацией #target1 и позже используется для свойства transform, а --y не указывается в <amp-animation> и поэтому запрашивается у элемента #target1. По умолчанию компонент имеет значение 0px, если он не определен и в CSS.

Более подробная информация` приведена в [разделе о выраженияхvar()иcalc()`](#var-and-calc-expressions).

Свойства времени

Анимация верхнего уровня и ее компоненты могут содержать свойства времени. Подробные сведения о них можно найти в разделе AnimationEffectTimingProperties спецификации по веб-анимации. В таблице ниже перечислены допустимые свойства.

Свойство Тип По умолчанию Описание
duration значение времени 0 Продолжительность анимации. Число в миллисекундах или значение времени CSS, например "2s".
delay значение времени 0 Задержка перед началом анимации. Число в миллисекундах или значение времени CSS, например "2s".
endDelay значение времени 0 Время между завершением анимации и моментом, как она считается завершенной. Число в миллисекундах или значение времени CSS, например "2s".
iterations число,
или Infinity ("бесконечность"),
или 1 infinite
1 Количество повторений анимационного эффекта.
iterationStart number/CSS 0 Смещение времени начала анимации.
easing строка linear ("линейно") Функция времени, используемая для настройки динамики.
direction строка normal ("обычная") normal ("обычная"), reverse ("обратная"), alternate ("переменная") или alternate-reverse ("обратная переменная").
fill строка none ("нет") none ("нет"), forwards ("вперед"), backwards ("назад"), both ("вперед и назад") или auto ("автоматически").

Для любого свойства времени допускается использовать числовые и строковые значения или значения CSS. Например, продолжительность (duration) можно задать как 1000, 1s или 1000ms. Кроме того, разрешены calc(), var() и другие выражения CSS.

Пример свойств времени в JSON:

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

Компоненты анимации наследуют свойства времени, настроенные для анимации верхнего уровня.

Subtargets

Везде, где можно указать selector, также доступен элемент subtargets: []. Он может переопределять свойства времени или переменные, определенные в анимации, для определенных подзадач, указанных в виде индекса или селектора CSS.

Пример:

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

В этом примере по умолчанию для всех целей, соответствующих .target, задана задержка 100 миллисекунд и значение 100 пикселей для --y. Однако задержка для первой цели (index: 0) переопределяется и становится равна 200 миллисекунд, а для лишних целей устанавливается значение 200 пикселей для --y.

Обратите внимание, что несколько элементов subtargets могут соответствовать одному элементу target.

Ключевые кадры

Ключевые кадры можно указывать различными способами, описанными в соответствующем разделе спецификации по веб-анимации, или как строку, ссылающуюся на имя @keyframes в CSS.

Ниже приведены типичные примеры определения ключевых кадров.

В кратком объектном формате с указанием конечного значения задается итоговое состояние 100 %:

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

В кратком объектном формате с указанием начального и конечного значений задаются начальное и итоговое состояния 0 % и 100 %:

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

В кратком объектном формате с указанием массива значений задается несколько значений для начального и итогового состояний, а также несколько смещений (с равными интервалами):

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

В форме массива определяются ключевые кадры. Смещения на 0 и 100 % назначаются автоматически и разделяются одинаковыми интервалами:

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

Форма массива также может включать смещение в явном виде:

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

В форме массива может задаваться динамика:

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

Другие форматы для ключевых кадров описаны в спецификации по веб-анимации.

Свойства могут принимать любые допустимые значения CSS, включая calc(), var() и другие выражения.

Ключевые кадры из CSS

Другой способ указать ключевые кадры – в таблице стилей документа (тег <style>) в виде правила CSS @keyframes. Пример:

<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 CSS по большей части сопоставим с встраиванием определения ключевых кадров JSON (см. спецификацию по веб-анимации). Однако есть некоторые особенности.

– Чтобы обеспечить поддержку широкого ряда платформ, могут потребоваться префиксы поставщиков, например @-ms-keyframes {} или -moz-transform. Префиксы поставщиков не нужны и не разрешены в формате JSON, но в CSS они могут быть необходимы. – Для платформ, которые не поддерживают выражения calc() и var(), нельзя использовать полифилы amp-animation, если ключевые кадры указаны в CSS. Поэтому рекомендуется всегда задавать в CSS резервные значения. – В CSS нельзя использовать расширения, такие как width(), height(), num(), rand(), index() и length().

Допустимые свойства для ключевых кадров

В ключевых кадрах можно использовать не все свойства CSS, а только такие, для которых современные браузеры способны быстро выполнять оптимизацию и анимацию. Список допустимых свойств, отвечающих требованиям к эффективности, растет. В настоящее время в него включены: – opacity; – transform; – visibility; – offset-distance.

Обратите внимание, что использовать свойства CSS с префиксом поставщика нет необходимости, и они не поддерживаются.

Сокращенные формы конфигурации анимации

Если анимация включает только один элемент и достаточно одного ключевого кадра, конфигурацию можно сократить только до этого компонента. Пример:

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

Если анимация состоит из ряда компонентов, но не включает верхний уровень, она может быть сокращена до массива компонентов. Пример:

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

Композиция анимаций

Анимации могут ссылаться друг на друга, таким образом объединяя несколько деклараций amp-animation в одну финальную анимацию. Этот метод в целом аналогичен встраиванию. Разделять анимации на разные элементы целесообразно, чтобы повторно использовать одну и ту же анимацию в другом месте или просто сделать каждую из них компактнее и легче в управлении.

Пример:

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

В этом примере анимация anim2 выступает частью anim1, а anim2 включена без цели (selector). В таком случае включенная анимация должна ссылаться на свою собственную цель.

Другая форма позволяет указать во включенной анимации одну или несколько целей. Включенная анимация при этом выполняется для каждой подходящей цели. Пример:

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

Здесь anim2 выполняется для каждой подходящей цели независимо от того, какому количеству элементов соответствует .target-class – одному, нескольким или ни одному.

Переменные и свойства времени, указанные в анимации вызова, также передаются во включенную анимацию.

Выражения var() и calc()

amp-animation позволяет использовать выражения var() и calc() для значений времени и ключевых кадров.

Пример:

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

И var(), и calc() применяются на платформах, где их поддержка изначально не предусмотрена. Свойства var() извлекаются из соответствующих целевых элементов. А свойство var(), к сожалению, использовать в качестве полифила нельзя. Поэтому если важна совместимость, настоятельно рекомендуется включать в выражения var() значения по умолчанию. Пример:

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

В компонентах анимации могут указываться собственные переменные в полях --var-name. Эти переменные добавляются во вложенные анимации и переопределяют переменные целевых элементов, указанных в таблице стилей (тег <style>). Выражения var() сначала пытаются обработать значения переменных, указанные в анимациях, а затем запрашивают целевые стили.

Расширения CSS

Компонент amp-animation предоставляет несколько расширений CSS для типичных задач, связанных с анимацией: rand(), num(), width() и height(). Эти функции могут использоваться везде, где amp-animation поддерживает значения CSS, в т. ч. со значениями времени и ключевых кадров.

Расширение CSS index()

Функция index() возвращает индекс текущего элемента цели (target) в эффекте анимации. Это наиболее актуально, когда к нескольким целям применяется один и тот же эффект анимации с помощью свойства selector. Первая цель, соответствующая селектору, будет иметь индекс 0, вторая – 1 и т. д.

Помимо других возможностей, это свойство можно комбинировать с выражениями calc() и использовать для создания эффекта стаи птиц (staggering). Пример:

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

Расширение CSS length()

Функция length() возвращает количество элементов цели в эффекте анимации. Актуально в сочетании с index():

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

Расширение CSS rand()

Функция rand() возвращает случайное значение CSS. У нее есть две формы.

Форма без аргументов просто возвращает случайное число от 0 до 1.

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

Во второй форме для функции задаются два аргумента, и она возвращает случайное значение между ними.

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

Расширения CSS width() и height()

Расширения width() и height() возвращают ширину и высоту анимированного или заданного селектором элемента. Значение возвращается в пикселях, например 100px.

Поддерживаются следующие формы: – width() и height() (ширина и высота анимированного элемента).

– width('.selector') и height('.selector') (ширина и высота элемента, заданного селектором). Подходит любой селектор CSS, например width('#container &gt; li').

– width(closest('.selector')) и height(closest('.selector')) (ширина и высота элемента, заданного ближайшим селектором).

Расширения width() и height() особенно полезны при трансформациях. left, top и подобные им свойства CSS, которые могут использовать значения % для выражения размера анимации пропорционально размеру контейнера. Однако свойство transform интерпретирует значения % по-другому – как процент от выбранного элемента. Таким образом, width() и height() могут использоваться для выражения трансформации относительно элементов контейнера и т. п.

Эти функции можно комбинировать с calc(), var() и другими выражениями CSS. Пример:

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

Расширение CSS num()

Функция num() возвращает значение CSS в числовой форме. Пример:

– num(11px) возвращает 11; – num(110ms) возвращает 110 и т. д.

Например, следующее выражение рассчитывает задержку в секундах, пропорциональную ширине элемента:

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

Анимация SVG

SVG – отличный инструмент, и мы очень рекомендуем использовать его для анимаций.

Для работы анимации SVG нужны те же свойства CSS, которые разрешены для ключевых кадров, с некоторыми особенностями:

  • Элементы SVG для браузеров Internet Explorer и Edge не поддерживают свойства CSS transform. Анимация transform сама является полифилом. Однако первоначальное состояние, определенное в таблице стилей, не применяется. Если оно имеет значение для этих браузеров, рекомендуется дублировать его через атрибут SVG transform.
  • В то время как свойство CSS transform является полифилом для Internet Explorer и Edge, задействовать в качестве полифила transform-origin невозможно. Таким образом, если требуется совместимость с Internet Explorer или Edge, рекомендуется использовать по умолчанию только transform-origin.
  • В большинстве браузеров в настоящее время возникают проблемы с интерпретацией свойства CSS transform-origin (подробнее: Chrome, Safari, Firefox). Большая часть подобных проблем обычно устраняется после реализации свойства CSS transform-box. В ситуации, когда имеет значение свойство transform-origin, рекомендуется также включить нужный файл CSS transform-box для обеспечения совместимости в будущем.

Запуск анимации

Анимация может быть инициирована с помощью атрибута trigger или действия on.

Атрибут trigger

В настоящее время visibility – единственное возможное значение атрибута trigger. ``Оно срабатывает, когда виден текущий документ или встроенный элемент (в области просмотра).

Пример:

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

Запуск с помощью действия on

Пример:

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

Действия on

Элемент amp-animation экспортирует следующие действия:

  • start. Запускает анимацию, если она ещё не запущена. Свойства и переменные времени могут быть указаны в качестве аргументов действия, например anim1.start(delay=-100, --scale=2).
  • restart. Запускает анимацию или перезапускает уже запущенную. Свойства и переменные времени могут быть указаны в качестве аргументов действия, например anim1.start(delay=-100, --scale=2).
  • pause. Приостанавливает запущенную анимацию.
  • resume. Запускает приостановленную анимацию.
  • togglePause. Приостанавливает и снова запускает анимацию.
  • seekTo. Приостанавливает анимацию и переходит к временной отметке, указанной аргументом time в миллисекундах или аргументом percent в виде процентной точки на шкале времени.
  • reverse. Запускает анимацию в обратном порядке.
  • finish. Завершает анимацию.
  • cancel. Отменяет воспроизведение анимации.
Need more help?

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