Angular(2+)动画API用法详解

2023-11-07

动画相关的 API 都是在 @angular/animations里面引入的。

import { 你想要的API } from '@angular/animations';
复制代码

trigger : 由它触发动画效果,称动画触发器。

function trigger(
            name: string, 
            definitions: AnimationMetadata[]  
         ):AnimationTriggerMetadata;
复制代码
  • name

    动画触发器名字, 如 growWidth

  • definitions

    要执行的动画, 如

    [ transition("void => *", [style({opacity: 0}), animate(600, style({ opacity: 1}))] )],

state :定义目标处于某一状态时的样式

function state(
            name: string, 
            styles: AnimationStyleMetadata,
            options?: {params: {[name: string]: any}}
         ):AnimationStateMetadata;
复制代码
  • name

    当前状态的名字,可以有多个名字,用逗号隔开,如:'active,clicked'
    这个name还可以用 void*表示: void代表动画执行前组件的状态; *代表动画执行后组件的状态,即组件的默认状态。

  • styles

    处于这个状态时的样式,如style({width: 0})

  • options : 可选项。

transition:状态之间转换处理函数

function transition(
            stateChangeExpr: string, 
            steps: AnimationMetadata | AnimationMetadata[], 
            options: AnimationOptions | null = null
         ):AnimationTransitionMetadata;
复制代码
  • stateChangeExpr

    A=>B,状态转换表达式,即从哪个状态切换到哪个状态。支持以下写法:

    1. 状态改变时启动动画
     transition("void => *", animate(500))
    复制代码
    1. 可以在两个状态变化上运行相同动画
    transition("void <=> *", animate(500)),
    复制代码
    1. 也可以定义几对状态切换执行同一动画
     transition("on => off, off => void", animate(500)),
    复制代码
  • steps

    animate(),动画执行步骤,即几秒执行完,执行曲线是怎样的。 如animate('100ms ease-in') 或是一个数组 [animate('100ms ease-in'),animate(600)]

  • options

    可以传入动画的延迟值和动画输入参数,以更改计时数据和样式。详见 AnimationOptions函数。

用法

其实状态 transition("void => *", animate(500))表示的是进入,在这里可以用 :enter 表示:

transition(":enter", animate(500))
复制代码

同理 transition(" *=> void", animate(500))离开可以这样写:

transition(":leave", animate(500)) 
复制代码

animate : 动画

function animate(
            timings: string | number,
            styles: AnimationStyleMetadata | AnimationKeyframesSequenceMetadata |null = null
          ): AnimationAnimateMetadata;
复制代码
  • timings : duration delay easing
    它是一个字符串,有三个参数:
    • duration : 动画持续时间
    • delay : 动画延迟几秒后开始
    • easing : 动画的缓和程度
      如果只有一个数字,那么会被认为是 duration 的值。如:
    animate("200 ease-in", ...)
    // 被编译成  duration=200, easing=ease-out
    
    animate("200 1000 ease-in", ...)
    // 被编译成  duration=200, delay=1000, easing=ease-out
    复制代码
  • styles
    它可以是 style(样式) 或 keyframes(关键帧),具体用法看下面详细介绍。
    animate(timings, style({ background: "red" }))
    animate(timings, keyframes([
      style({ background: "blue", offset: 0.2})),  // 20%
      style({ background: "red", offset: 1}))   // 100%
    ])
    复制代码

style : 样式设置

function style(
            tokens: '*' |
            {[key: string]: string | number} |
            Array<'*'|{[key: string]: string | number}>
         ): AnimationStyleMetadata;
复制代码

style声明一个包含CSS属性/样式的键值对。

style({ width: 100, height: 0 })
复制代码

Auto-styles(自适应样式): style值可以用 '*' 来表示,自动达到其原本的样式,举个例子你就明白作用了:

如果一个div它实际宽度是100px,高度为100px,让它高度从0 到100px变化

<div class='demo'></div>
...
.demo{
    width: 100px;
    height: 100px;
}
复制代码

这时候用 '*'来写

 animations: [trigger(
      'autoHeight',
      [
        state('void', style({height: '0px'})),
        state('*', style({height: '*'})),
        transition('void => *',  animate(500))
      ])],

复制代码

它就会在 500ms内 高度从 0 搭配100px。咦,似乎没感觉到什么作用...
在高度为动态获取的值时候就看到其强大了:data为动态获取的{ height: xxx }

<div class='demo' [ngStyle]="{'height':data.height}">
</div>
...
.demo{
    width: 100px;
}

复制代码
 animations: [trigger(
      'autoHeight',
      [
        state('void', style({height: '0px'})),
        state('*', style({height: '*'})),
        transition('void => *',  animate(500))
      ])],

复制代码

这样在 500ms 高度自动到达设定的值。

keyframes:关键帧

function keyframes(
             steps: AnimationStyleMetadata[]
         ): AnimationKeyframesSequenceMetadata;
复制代码

它的参数是一个style()的数组,表示步骤。

animate("5s", keyframes([
  style({ backgroundColor: "red", offset: 0 }),  // 0%
  style({ backgroundColor: "blue", offset: 0.2 }), // 20%
  style({ backgroundColor: "orange", offset: 0.3 }), // 30%
  style({ backgroundColor: "black", offset: 1 })   // 100%
]))
复制代码

这里的 offset 和css3 keyframes里面的百分比一样,是时间的偏移量。
offset: 0.2表示动画在 20%的时候的样式。

此外,如果没有设置偏移量,那么偏移量将自动计算

animate("5s", keyframes([
  style({ backgroundColor: "red" }) // offset = 0
  style({ backgroundColor: "blue" }) // offset = 0.33
  style({ backgroundColor: "orange" }) // offset = 0.66
  style({ backgroundColor: "black" }) // offset = 1
]))
复制代码

query: 选取元素,并添加动画

function query(
            selector: string, 
            animation: AnimationMetadata | AnimationMetadata[], 
            options: AnimationQueryOptions | null = null
         ): AnimationQueryMetadata;
复制代码
  • selector : 要选取的元素,选取方式和原生的一样。
  • animation : 要进行的动画序列,一个或多个。
作用:

在处于动画序列的元素内部查找一个或多个元素,这些元素也会被加入当前动画序列中,不过一般会重新写一个数组来重新定义选取元素的动画序列。

用法:

1) 选取元素并可以限制数量
query()函数源码中使用了element.querySelectorAll因此他可以选取多个元素,所以我们在选取元素的时候可以加上一个 limit 来限制选取的数量。

// 在class为 demo的div里找一个div,找到的是 demo1,如果 limit为2 的话找到的是 [demo1, demo2]。
template: `
  <div [@queryDemo] class='demo'>
    <div class='demo1'></div>
    <div class='demo2'></div>
  </div>
`,
animations: [
   trigger('queryDemo', [
     transition('void => *', [
          query( 'div', animate(...), {limit: 1} )
     ])
   ]
]
复制代码

2) 报错功能
默认情况下如果选取的元素找不到则 query()函数会报错,设置optional选项为 true 则或忽略错误。

query('.demo-not-be-there', [
  animate(...),
  animate(...)
], { optional: true })
复制代码
选择器的特殊值

query()函数里面用伪选择器可以选出特定的元素:

  • query(":enter")/query(":leave") : 选取新插入 / 移除的元素
  • query(":animating") : 选取所有正在进行动画的元素
  • query("@triggerName") : 选取有特定触发器的元素
  • query("@*") : 选取所有具有触发器的元素
  • query(":self") : 把当前元素增加到动画序列中

多个伪选择器可以合在一起组成选择器查询字符串:

query(':self, .record:enter, .record:leave, @subTrigger', [...])
复制代码
例子
@Component({
  selector: 'inner',
  template: `
    <div [@queryAnimation]="exp">
      <h1>Title</h1>
      <div class="content">
        Blah blah blah
      </div>
    </div>
  `,
  animations: [
   trigger('queryAnimation', [
     transition('* => goAnimate', [
       // 隐藏里面的元素
       query('h1', style({ opacity: 0 })),
       query('.content', style({ opacity: 0 })),
 
       // 一个一个地执行里面元素的动画
       query('h1', animate(1000, style({ opacity: 1 })),
       query('.content', animate(1000, style({ opacity: 1 })),
     ])
   ])
 ]
})
class Cmp {
  exp = '';
 
  goAnimate() {
    this.exp = 'goAnimate';
  }
}
复制代码

sequence : 序列

function sequence(
            steps: AnimationMetadata[], 
            options: AnimationOptions | null = null
         ): AnimationSequenceMetadata;
复制代码
  • steps : 动画序列的步骤

它可以由样式或动画函数调用组成。对style()的调用将立即应用提供的样式数据,而对animate()的调用将在它延迟时间后应用它的样式数据。

  • options: 参见 AnimationOptions
// 这是一个动画序列
sequence([
  style({ opacity: 0 })),
  animate("1s", { opacity: 1 }))
])
复制代码
那到底什么是序列呢?

它是一个动画列表[A,B,C],里面的动画挨个执行:执行完A再执行B,B执行完再执行C。 它可以应用在 grouptransition里面,它只会在每个内部动画步骤完成后再继续执行下一条指令。

将一个数组作为动画数据传递到transition时,默认使用序列。如下面的[animate(500, style({...})), animate(500)]就是序列。

 animations: [trigger(
      'demo',
      [
        state('void', style({...})),
        state('*', style({...})),
        transition(
            'void => *', [animate(500, style({...})), animate(500)])
      ])],
复制代码
它和组(group)的异同:

都是动画列表,序列是一个一个执行,组是并行执行。

group : 组

function group(
            steps: AnimationMetadata[],
            options: AnimationOptions | null = null
         ): AnimationGroupMetadata;
复制代码
  • steps : 动画步骤数据
    它可以由样式或动画函数调用组成。在一个组中,每个样式或动画函数的调用都会立即同时执行,当然你可以使用关键帧或者动画的延迟函数来延迟执行动画。
  • options: 参见 AnimationOptions
group([
  animate("1s", { background: "black" }))
  animate("2s", { color: "white" }))
])
复制代码
什么是组呢?

组是一个并行运行的动画步骤列表。当存在很多样式在不同时间段开始或结束动画,我们需要对它统一进行管理的时候作用非常明显。利用组我们可以轻易控制它们同时开始动画或者同时结束动画。
group函数既可以在序列(sequence)中使用,也可以在转换(transition)中使用,它只会在所有内部动画步骤完成后继续执行下一条指令。

group官网介绍

AnimationOptions :动画的可选项

import { AnimationOptions } from '@angular/animations';
复制代码
interface AnimationOptions { 
  delay?: number|string
  params?: {[name: string]: any}
}
复制代码
  • delay: number|string
    动画的延迟值。
  • params
    在启动动画时传入参数,以更改样式。
以下动画函数可配置 AnimationOptions:
  • transition()
  • sequence()
  • group()
  • query()
  • animation()
  • useAnimation()
  • animateChild()
  • 使用AnimationBuilder服务构建的动画
子接口
  • AnimateChildOptions
  • AnimationQueryOptions

实例: 比如现在想做一个动画效果 : 点击按钮 div 宽从 0 到100px。

  1. 添加动画触发器
// ts
import { trigger } from '@angular/core';

@Component({
  templateUrl: 'my-demo.html',
  animations: [
    trigger( 'growWidth', [ // 这里是定义的一些动画效果] )
  ]
})

// html
<div [@growWidth]>...</div>
复制代码
  1. 再进行状态(宽度)的改变
import { trigger, state, style } from '@angular/core';

@Component({
  templateUrl: 'my-demo.html',
  animations: [
    trigger( 'growWidth', [ 
         state( 'smWidth, void', style({width: '0px'}) ),
         state( 'lgWidth', style({width: '100px'}) )
    ] )
  ]
})

复制代码

上面定义了两个状态,一个是宽度最小时候为0,一个宽度最大时候为 100px; 那么有growWidth 动画触发器的 div 会完成这个宽度 0 到100px的动画。

  1. 上面虽然完成了两个不同状态之间的改变,但是没有过渡效果,用transition实现过渡。
import { trigger, state, transition, animate } from '@angular/core';

@Component({
  templateUrl: 'my-demo.html',
  animations: [
    trigger( 'growWidth', [ 
         state( 'smWidth, void', style({width: '0px'}) ),
         state( 'lgWidth', style({width: '100px'}) ),
         transition('smWidth => lgWidth', animate(600)),
         transition('lgWidth => smWidth', animate(600)),
    ] )
  ]
})

复制代码

上面规定了从 smWidth 状态到 lgWidth状态需要0.6s的时间,所以可以看到div的宽度是慢慢变大的。

| 更多API用法更新于 github

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Angular(2+)动画API用法详解 的相关文章

  • 如何在同一页面上使用AJAX处理多个表单

    我有一个表单 当我单击 提交 时 它就被提交了 然后该表单隐藏 操作页面的结果显示在 div 中 classname dig 它工作正常 但是当我添加另一个表单时 它停止正常工作并且所有表单同时提交 我如何更改我的代码 done click
  • 每 3 秒重复一次动画

    我正在使用 WOW js 和 animate css 现在我正在将 CSS 运行到 Infinite 我想知道如何让我的课程运行 3 秒停止并再次开始到无限 My html img src images fork png class for
  • 为什么 JavaScript base-36 转换看起来不明确

    我目前正在编写一段使用 Base 36 编码的 JavaScript 我遇到了这个问题 parseInt welcomeback 36 toString 36 看来要回归了 welcomebacg 我在 Chrome 开发者控制台和 Nod
  • 尝试将布尔 C# 变量传递给 javascript 变量并将其设置为 true

    在我的 aspx 页面中 我将布尔变量 C 传递给需要布尔类型的 javascript 函数 但遇到了问题 但是 C 变量返回 True 而 javascript 不喜欢大写 myjavascript 如果我将 c 变量转换为字符串 那么我
  • Web 串行 API - 未捕获(承诺中)DOMException:无法打开串行端口/所需成员 baudRate 未定义

    下面的代码可以在我的 Xubuntu 机器上运行 但现在我在 Kubuntu 上 它不再工作了 它不会打开端口 Arduino IDE 工作正常 可以向开发板写入代码 并且我可以在 Chrome 中选择设备 Arduino Uno 但当我尝
  • TypeError: props.render 不是一个函数(React hook 形式)

    我将方法作为我用react hook form制作的形式的道具传递 当从react hook form添加控制器时 它给了我 TypeError props render不是一个函数 我在网上找不到任何解决方案 因此感谢任何帮助 impor
  • 如何重置使用 JavaScript 更改的 CSS 属性?

    我的导航按钮的宽度从 100px 增加到 150px 当鼠标悬停在 nav li hover width 150px 但是使用 javascript 我已经做到了 无论选择哪个选项 宽度都将继续为 150px 当选择每个选项时 它会使其他选
  • 使用模数按字母顺序对列表进行排序

    我在获取元素列表并按字母顺序对它们进行排序方面没有任何问题 但我很难理解如何使用模数来做到这一点 更新 这是按我的方式工作的代码 但是 我更喜欢下面提供的答案的可重用性 因此接受了该答案
  • 在 Wordpress 站点中进行 AJAX 调用时出现问题

    我在使用 Wordpress 站点功能的 AJAX 部分时遇到了一些问题 该功能接受在表单上输入的邮政编码 使用 PHP 函数来查找邮政编码是否引用特定位置并返回到该位置的永久链接 我的第一个问题是关于我构建的表单 现在我的表单操作是空白的
  • JavaScript 重定向到新窗口

    我有以下代码 它根据下拉列表的值重定向到页面 我如何使其在新窗口中打开 function goto form var index form select selectedIndex if form select options index
  • 如何将 Google Charts 与 Vue.js 库一起使用?

    我正在尝试使用 Vue js 库使用 Google Charts 制作图表 但我不知道如何添加到 div 这是我尝试做的 这是如何使用普通 javascript 添加图表 这是文档的代码示例 https developers google
  • 使用 KnockoutJs 映射插件进行递归模板化

    我正在尝试使用以下方法在树上进行递归模板化ko映射 插入 http knockoutjs com documentation plugins mapping html 但我无法渲染它 除非我定义separate每个级别的模板 在以下情况下
  • 跟踪用户何时点击浏览器上的后退按钮

    是否可以检测用户何时单击浏览器的后退按钮 我有一个 Ajax 应用程序 如果我可以检测到用户何时单击后退按钮 我可以显示适当的数据 任何使用 PHP JavaScript 的解决方案都是优选的 任何语言的解决方案都可以 只需要我可以翻译成
  • 在 webpack 2.x 中使用 autoprefixer 和 postcss

    如何使用autoprefixer使用 webpack 2 x 以前 它曾经是这样的 module loaders test scss loader style css sass postcss postcss gt return autop
  • 提交表单并重定向页面

    我在 SO 上看到了很多与此相关的其他问题 但没有一个对我有用 我正在尝试提交POST表单 然后将用户重定向到另一个页面 但我无法同时实现这两种情况 我可以获取重定向或帖子 但不能同时获取两者 这是我现在所拥有的
  • 为 illustrator 导出脚本以保存为 web jpg

    任何人都可以帮我为 illustrator CC2017 编写一个脚本 将文件以 JPG 格式导出到网络 旧版 然后保存文件并关闭 我有 700 个文件 每个文件有 2 个画板 单击 文件 gt 导出 gt 另存为 Web 旧版 然后右键文
  • 为什么在 Internet Explorer 中访问 localStorage 对象会引发错误?

    我正在解决一个客户端问题 Modernizr 意外地没有检测到对localStorageInternet Explorer 9 中的对象 我的页面正确使用 HTML 5 文档类型 并且开发人员工具报告该页面具有 IE9 的浏览器模式和 IE
  • 为什么我不能在 AngularJS 中使用 data-* 作为指令的属性名称?

    On the t他的笨蛋 http plnkr co edit l3KoY3 p preview您可以注意到属性名称模式的奇怪行为data 在指令中 电话 Test of data named attribute br
  • 在 vue.js 中访问数组对象属性

    给定以下数组vue js packageMaps Object packageMap 0 Object Id 16 PackageType flag list ProductCode F BannerBase packageMap 1 Ob
  • 如何更改此 jquery 插件的时区/时间戳?

    我正在使用这个名为 timeago 的插件 在这里找到 timeago yarp com 它工作得很好 只是它在似乎不同的时区运行 我住在美国东部 费城时区 当我将准确的 EST 时间放入 timeago 插件时 比如 2011 05 28

随机推荐

  • 详解union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=‘ ‘--+

    此文章是记录本人对知识理解的随手笔记 内容不肯定百分百正确 如有错误望指出并谅解 1 group concat函数是将查询到的每行结果以某个字段名进行合并 每一行合并的结果以逗号分隔开 可以结合以下例子理解 下图是没使用group conc
  • gym 自己环境搭建

    http t csdn cn ILs89http t csdn cn ILs89发现gym envs文件夹下的 init 可以不加from import 只需要注册相应文件夹下的自己的环境就好 值得注意的 需要指定好文件路径 gym env
  • 20230816 图像处理

    1 2022 图像检索资料总结 知乎 2 高斯金字塔与拉普拉斯金字塔的原理与python构建 3 一篇文章为你讲透双线性插值 知乎 4 图像处理基础 图像滤波 知乎 5 高斯分布的应用 高斯分布实际用途 又要起名字了的博客 CSDN博客 6
  • Android 实现护眼模式

    一 背景 在阅读软件或者儿童软件都需要护眼模式来降低蓝光的辐射 二 实现方案 首先在每个activity创建的时候在最上层添加一层view 去掉点击事件 用sp或者mmkv来存储当前是否打开护眼模式 在每次activity onresume
  • 二.基于nodejs express multer 上传图片功能实现+详细说明_番茄出品

    START 前几天熬夜做了一个基于nodejs的后端服务 连接mysql数据库搞定了 但是最近遇到上传图片一个需求 这如何实现呢 别着急 番茄带你一点一点实现 本文作者 lazy tomato 编写时间 2022 03 31 22 21 前
  • Linux教程:YUM与开源项目实战(Web运维)

    1 了解Linux软件的安装方式 2 掌握更新yum源 3 掌握YUM软件安装方式 4 了解LAMP环境以及AMP的关系 5 了解阿里云ECS的创建过程 6 能够yum方式搭建lamp环境 7 能够实现Discuz 论坛部署 8 能够购买域
  • Django入门教程

    Django入门教程 创建Django项目 django admin startproject mysite 这将在目录下生成一个mysite目录 也就是你的这个Django项目的根目录 它包含了一系列自动生成的目录和文件 具备各自专有的用
  • 聊聊FFT(二)----幅值、模值与分辨率

    以常见的家用交流220V 以下称AC220V 工频电信号为例 大家都知道家里的插座内有220V的电 可以给电饭锅 热水壶 空调冰箱等等电器供电 至于220V具体指的是什么可能非理工科背景的同学没有深究过 有效值又称 均方根值 一种用以计量交
  • 使用docker安装我们的ES启动时的异常解决

    一开始我启动失败 我一直是以为我们的内存大小分配的问题 es默认启动占用内存是2g docker run e ES JAVA OPTS Xms256m Xmx256m id p 1001 1001 p 9301 9301 v home es
  • CSDN周赛62期反馈及简要题解

    持续了十期的 计算之魂 主题周赛告一段落 可能上周就已经告一段落了 以致于也出现了重复的考题 这本书确实不错 里面提到的计算机思维我认为是理解和学习计算机科学的基础 第一次读此书的时候就一口气读到第八章 读到精彩之处 不禁拍案叫绝 在此也强
  • 三、Esp32引脚资源详细

    三 Esp32引脚资源详细 文章目录 三 Esp32引脚资源详细 3 1 仅输入引脚 3 2 SPI闪存 3 3 电容式触摸GPIO 3 4 模数转换器 ADC 3 5 数模转换器 DAC 3 6 RTC GPIOs 3 7 脉冲宽度调制
  • HashMap的面试题

    目录 1 底层数据结构 1 7和1 8有何不同 2 为什么用红黑树 为何不一上来就树化 树化阈值为何是8 何时会树化 何时会退化为链表 3 索引如何计算 hashCode都有了 为何还要提供hash 方法 数组容量为何是2的n次幂 4 Ha
  • C语言,使用指针计算每行最大值,每列最小值 ,void Max(int (*p)[],int line,int row) ,void Min(int (*p)[],int line,in

    使用指针计算每行最大值 每列最小值 void Max int p int line int row void Min int p int line int row include
  • Pandas基础(全)

    Pandas基础 全 引言 Pandas是基于Numpy的库 但功能更加强大 Numpy专注于数值型数据的操作 而Pandas对数值型 字符串型等多种格式的表格数据都有很好的支持 关于Numpy的基础知识 请查看 Numpy基础 全 内容介
  • 三相LCL变流器PR控制仿真及验证

    三相变流器 可单位功率因数整流 实现母线电压的泵升 可逆变并网实现能量回馈 它是一个三相AC DC双向电源 基于三相全控型半桥的双向变流器可用于很多领域 1 中大功率变频传动领域 例如电梯 可用于电梯下降过程中的能量回馈 大大节省电能 电梯
  • 网上传说软件测试培训真的那么黑心吗?都是骗局?

    今天一大早社区群因为 软件测试培训班靠不靠谱 的话题炸开了锅 就客观事实而言 当下的软件测试早已不复当年的混乱 再想说0基础进入软测行业 靠着一路摸爬滚打在工作中从无到有学会软测 如果没有贵人扶持 怕是万难 据相关调查数据显示 有79 53
  • windows server 2008 r2 搭建文件服务器

    windows server 2008 r2 搭建文件服务器 目的需求 在测试环境下模拟公司现状需求 利用windows server 搭建文件服务器 工具必备 1 vmware workstation 2 windows server 2
  • 图像处理中的卷积

    卷积是积分变换的方法 其在许多方面有广泛应用 卷积通过两个函数 f 和 g 生成第三个函数 可以看作是两个变量在某范围内相乘后求和的结果 设 f x g x 是两个可积函数 作积分 可以证明上述积分的存在性 随着x取值的不同 这个积分就定义
  • 展示PyEcharts图表到Django框架前端页面教程(逐步教程)

    官网教程参考 https pyecharts org zh cn web django id django e6 a8 a1 e6 9d bf e6 b8 b2 e6 9f 93 这篇博客与官网一样使用Ajax 不使用ajax 直接填充一个
  • Angular(2+)动画API用法详解

    动画相关的 API 都是在 angular animations里面引入的 import 你想要的API from angular animations 复制代码 trigger 由它触发动画效果 称动画触发器 function trigg