">文档:<amp-animation> - amp.dev - AMP 框架
AMP

amp-animation

描述

定义并显示动画。

 

必需脚本

<script async custom-element="amp-animation" src="https://cdn.ampproject.org/v0/amp-animation-0.1.js"></script>

支持的布局

用法

amp-animation 组件定义并运行自定义动画和效果。它依赖于 Web Animations API

amp-animation 组件以 JSON 结构定义动画。顶级部分通过声明目标元素、执行条件、时序属性和 关键帧效果 来定义总体动画。总体过程可以在 animations 数组中包含任意数量的动画部分。动画数组中的动画部分可能有其自己的目标元素、执行条件、时序属性和关键帧效果。

<amp-animation layout="nodisplay">
  <script type="application/json">
    {
      "selector": "#target-id",
      "duration": "1s",
      "iterations": "4",
      "fill": "both",
      "direction": "alternate",
      "animations": [
        {
          "selector": ".target-class",
          "easing": "cubic-bezier(0,0,.21,1)",
          "keyframes": {
            "transform": "rotate(20deg)"
          }
        },
        {
          "delay": "2s",
          "easing": "cubic-bezier(0,0,.21,1)",
          "keyframes": {
            "transform": "rotate(30deg)"
          }
        }
      ]
    }
  </script>
</amp-animation>

如果动画使用单个元素和单个关键帧效果,则配置作为单个动画定义有效。

<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": ".target1",
        "duration": 1000,
        "keyframes": {"opacity": 1}
      },
      {
        "selector": ".target2",
        "duration": 600,
        "delay": 400,
        "keyframes": {"transform": "scale(2)"}
      }
    ]
  </script>
</amp-animation>

通过 trigger 属性或 操作 触发一个或多个动画的开始。

你可以将通过操作控制的 amp-animation 放置在 DOM 中的任何位置。如果动画包含 trigger="visibility",它会在父元素进入视口时触发,并在父元素离开视口时暂停。

定义效果

关键帧

你必须将效果声明为关键帧,才能使用 amp-animations 应用动画。

你可以按照 MDN 的 关键帧格式 中定义的方式在 amp-animation 中指定关键帧。你还可以引用在 <style amp-custom><style amp-keyframes> 标签中作为 CSS 定义的 @keyframes 名称。

下面是一些关键帧定义的典型示例。

简写对象形式的“to”格式指定 100% 时的最终状态

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

简写对象形式的“from-to”格式指定 0 和 100% 时的开始和结束状态

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

简写对象形式的“value-array”格式为开始、结束状态和多个(等间距)偏移量指定多个值

{
  "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)"}
  ]
}

数组形式还可以明确包含“offset”

{
  "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)"}
  ]
}

使用 @keyframes CSS 规则

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

大多数 CSS @keyframes 匹配 Web Animations 规范 中 JSON 内联关键帧定义,并带有以下细微差别

  • 您可能需要供应商前缀,例如 @-ms-keyframes {}-moz-transform 以获得广泛平台支持。JSON 格式不需要供应商前缀,也不允许供应商前缀,但在 CSS 中可能需要。

  • 在不受支持的平台上,当在 CSS 中指定关键帧时,amp-animation 的填充将因使用 calc()var() 而失败。使用 CSS 中的备用值来避免这种情况。

  • width()height()x()y()num()rand()index()length() 等 CSS 扩展不可用于 @keyframes

prefers-reduced-motion

通常,正在运行的动画将通过将元素置于可见状态来完成,而初始 CSS 将隐藏元素,以依赖于稍后完成的动画。

用户可以将他们的设备配置为 使用减少的动画。使用此选项,动画将根本不会运行。在这种情况下,您需要禁用依赖于稍后运行的动画的 CSS 属性。

您可以为此目的使用媒体查询。在以下示例中,<amp-animation> 将稍后通过设置 opacity: 1 将元素动画为可见。当动画被禁用时,元素始终可见

<style amp-custom>
  .my-hidden-element {
    opacity: 1;
  }
  @media not (prefers-reduced-motion) {
    .my-hidden-element {
      opacity: 0;
    }
  }
</style>
<amp-animation layout="nodisplay">
  <script type="application/json">
    [
      {
        "selector": ".my-hidden-element",
        "duration": "1s",
        "keyframes": {"opacity": 1}
      }
    ]
  </script>
</amp-animation>
关键帧允许的属性

amp-animation 组件限制 CSS 允许的属性以优化性能。以下是允许列出的属性

不需要也不允许使用供应商前缀 CSS 属性。

时间属性

顶级动画和动画组件可能包含时序属性。以下是允许的属性集

属性 类型 默认值 描述
duration 时间 0 动画持续时间。以毫秒为单位的数字值或 CSS 时间值,例如 2s
delay 时间 0 动画开始执行前的延迟。以毫秒为单位的数字值或 CSS 时间值,例如 2s
endDelay 时间 0 动画完成后到实际被认为完成之前的时间延迟。以毫秒为单位的数字值或 CSS 时间值,例如 2s
迭代 数字或
“Infinity”或
“infinite”
1 动画效果重复的次数。
iterationStart 数字/CSS 0 效果开始动画的时间偏移。
easing 字符串 “linear” 用于缩放时间以产生缓动效果的时序函数
direction 字符串 “normal” “normal”、“reverse”、“alternate”或“alternate-reverse”之一。
fill 字符串 “none” “none”、“forwards”、“backwards”、“both”、“auto”之一。

所有时序属性都允许直接数字/字符串值或 CSS 值。例如,10001s1000m 都是 duration 的有效值。

JSON 中时序属性的示例

{
  ...
  "duration": "1s",
  "delay": 100,
  "easing": "ease-in",
  "fill": "both"
  ...
}

动画组件继承为顶级动画指定的时序属性。

变量和计算表达式

amp-animation 允许使用 var()calc()min()max() 表达式作为时序和关键帧值。

<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() 表达式声明 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 传播到嵌套动画中,但它被覆盖。最终的平移值是 150px

  • --y<amp-animation> 组件中任何地方都没有指定。如果查询未在 <amp style-custom> 标记内的 CSS 中找到其定义,则其默认为 0px

Polyfill 适用于受支持平台上的 var()calc()。最佳做法是为 var() 包含默认值。

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

通过在 amp-animation 组件中使用 --var-name 字段,覆盖在 <style amp-custom> 标记中指定的目标元素的变量。var() 表达式首先尝试解析在动画组件中指定的变量,然后解析目标样式。

CSS 扩展

amp-animation 组件提供了以下 CSS 扩展:rand()num()width()height()x()y()。允许的 CSS 扩展在 amp-animation 定义中可以使用 CSS 值的任何地方都是有效的。这包括时序和关键帧值。

CSS index() 扩展

index() 函数返回动画效果中当前目标元素的索引。在使用 selector 属性对多个目标执行相同的动画时,此函数最为相关。selector 匹配的第一个目标的 index 为 0,第二个目标的 index 为 1,依此类推。

此属性除其他用途外,还可以与 calc() 表达式结合使用,以创建交错效果。例如

{
  "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()x()y() 扩展

width()/height()x()/y() 扩展返回动画元素或由选择器指定元素的大小或坐标。返回的值以像素为单位,例如 100px

amp-animation 支持以下形式

  • width()height()x()y() - 动画元素的宽度/高度或坐标。

  • 使用选择器,例如 width('.selector')x('.selector') - 由选择器指定的元素的尺寸或坐标。任何 CSS 选择器均可用。例如,height('#container > li')

  • 使用最接近选择器,例如 height(closest('.selector'))y(closest('.selector')) - 由最接近选择器指定的元素的尺寸或坐标。

width()height() 对于变换特别有用。lefttop 和类似的 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)"
}

覆盖子目标上的效果

使用子目标覆盖顶级动画中定义的时间属性或变量。在与有效 selector 相同的空间中,在需要的地方通过 subtargets: [] 定义子目标。按索引或 CSS 选择器指定子目标。

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

在上面的示例中

  • 顶级动画将 ".target" 匹配的目标的默认延迟设置为 100,并将 "--y" 设置为 100px

  • "subtargets": [] 包含第一个目标,"index": 0。此定义将默认延迟从 100 覆盖为 200

  • "subtargets": [] 包含 "selector": ":nth-child(2n+1)"。此定义将 --y 变量的默认值从 100px 覆盖为 200px

多个子目标可以匹配一个目标 selector 元素。

SVG 动画

SVG 很棒,我们建议将其用于动画!

amp-animation 组件支持 SVG 动画,其中列出了允许的 CSS 关键帧属性,并带有以下细微差别

  • IE/Edge SVG 元素 不支持 CSS transform 属性。虽然 transform 动画本身是填充的,但样式表中定义的初始状态不会应用。如果初始转换状态在 IE/Edge 中很重要,建议通过 SVG transform 属性 复制它。

  • 不可能为 IE/Edge 填充 transform-origin。为了兼容性,仅使用默认的 transform-origin

  • 使用 CSS transform-box 以避免 transform-origin 解释问题。请参阅 ChromeSafariFirefox 的问题。

兼容性和后备

使用媒体查询、支持条件和 switch 语句以实现平台兼容性和后备选项。

媒体查询

使用 media 属性指定媒体查询。此属性可以包含 Window.matchMedia API 允许的任何表达式,并且对应于 @media CSS 规则。

指定后,仅当环境支持指定的 CSS 功能时,动画组件才会执行。

支持条件

使用 supports 属性指定支持条件。supports 属性包含 CSS.supports API 允许的任何表达式,并且对应于 @supports CSS 规则。

指定后,仅当环境支持指定的 CSS 功能时,动画组件才会执行。

动画 switch 语句

在某些情况下,您可能需要将条件动画与可选默认值组合到单个动画中。使用 switch 动画语句定义条件。

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

amp-animation 组件按定义的顺序评估 switch 动画定义。它执行第一个与条件匹配的动画,并忽略其余动画。

在下面的示例中,如果支持,动画将运行运动路径动画,并回退到转换

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

组合和拆分动画

amp-animation 中定义的动画可以相互引用。此功能允许将多个 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"执行。在调用者动画中指定的变量和计时属性传递到组合动画。

通过 on 操作触发

例如

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

动画的可访问性考虑因素

如果您使用动画来传达含义或内容,请确保也以其他形式传达给可能无法看到这些动画的用户。在最基本级别上,确保您的文本内容传达与动画相同的信息。例如,如果您使用<amp-animation>来说明流程中的步骤序列,请确保还有文本(在同一页面上或在链接的页面中)用文字描述相同的步骤序列。

动画通常不能由用户暂停/停止。根据动画的类型、大小以及是否循环/重复,这可能是一种轻微的干扰,或者对某些用户组来说是一个大问题——特别是如果动画包含快速闪烁的颜色变化。一般来说,我们建议避免使用大型、无限重复的动画,除非您确定它们不会对用户产生不利影响。考虑提供一个控件,允许用户暂停动画。考虑利用prefers-reduced-motion媒体查询,并且只有在用户没有表示偏好减少运动/动画时才使动画生效。

<amp-animation ... media="not (prefers-reduced-motion: reduce)">
  <!-- this animation will only play if the user has *not*
       expressed a preference for reduced motion -->
  ...
</amp-animation>

您可以进一步采取措施,提供单独的、更微妙的备用动画,以便在prefers-reduced-motion: reduce评估为 true 时生效,或者拆分出较小的动画,无论媒体功能如何,这些动画都应该在所有情况下发生。

<amp-animation ... media="(prefers-reduced-motion: reduce)">
  <!-- fallback subtle animation effects that only play if the user
       has expressed a preference for reduced motion -->
  ...
</amp-animation>

<amp-animation ...>
  <!-- general/common animation effects that will take effect
       regardless of any user preference for reduced motion -->
  ...
</amp-animation>

请参阅MDN - prefers-reduced-motionweb.dev - prefers-reduced-motion: 有时较少的动作更好中的这篇文章,以了解更多详细信息。

对于不纯粹是装饰性/视觉效果的动画,而是实际传达信息的动画,请确保任何重要的文本和图形/非文本元素具有足够的颜色对比度。请参阅web.dev 颜色和对比度可访问性以了解简介(主要围绕文本对比度)和Knowbility: 探索 WCAG 2.1 — 1.4.11 非文本对比度以了解有关非文本元素的更多详细信息。

属性

触发器

确定何时应触发动画。这必须设置为visibility,以便动画在故事页面变为可见且处于活动状态时开始。

布局

应始终为nodisplay

id(可选)

动画组件的id。用于引用动画和链接一系列动画。

操作

开始

如果动画尚未运行,则启动动画。时序属性和变量。可以指定为操作参数。例如:anim1.start(delay=-100, --scale=2)

重新开始

启动动画或重新启动当前正在运行的动画。时序属性和变量。可以指定为操作参数。例如:anim1.start(delay=-100, --scale=2)

暂停

暂停当前正在运行的动画。

恢复

恢复当前正在运行的动画。

切换暂停

切换暂停/恢复操作。

seekTo

暂停动画并根据以毫秒为单位的time参数或以时间线中百分点为单位的percent参数指定的时间点进行查找。

反转

反转动画。

完成

完成动画。

取消

取消动画。

amp-story 用法

如果您想将<amp-animation><amp-story>一起使用,请注意您应该使用<amp-story-animation>。有关如何使用它的更多信息,请参阅文档的高级动画部分。

验证

请参阅 AMP 验证器规范中的amp-animation规则

需要更多帮助?

您已经阅读了本文档十几次,但它并没有真正涵盖您所有的问题?也许其他人也有同感:在 Stack Overflow 上联系他们。

转到 Stack Overflow
发现错误或缺少功能?

AMP 项目强烈鼓励您参与和贡献!我们希望您成为我们开源社区的持续参与者,但我们也欢迎您对您特别热衷的问题做出一次性贡献。

转到 GitHub