动机
现代Web组件经常使用动画。级联样式表(CSS)为开发人员提供了创建令人印象深刻的动画的工具。使用CSS可以实现属性转换,唯一命名的动画,多部分关键帧。由于CSS,动画可能性是无穷无尽的。
在现代Web应用程序中,动画集中了用户的注意力。良好的动画旨在以令人满意的,富有成效的方式引导用户的注意力。动画不应该对用户造成烦扰。
动画以动作的形式提供反馈。它们向用户显示应用程序正在主动处理其请求。当应用程序必须加载时,像可见按钮按下或加载器这样简单的东西会吸引用户的注意力。
动画在Angular的案例中继续变得越来越重要。 Google在推广Material Design理念的同时开发了Angular。它鼓励简洁的用户界面(UI),并辅以动画用户反馈。它使Web应用程序感觉有点活泼,使用起来很有趣。
Angular社区开发了一个名为Material2的核心小部件库。该项目为Angular添加了各种小部件模块。其中大多数都以动画为特色。为了理解它们的工作原理,本文建议在阅读之前研究CSS动画。
角度动画是CSS原生提供的框架的简化版本。 CSS是Web浏览器中出现的Angular动画的核心技术。但CSS超出了本文的范围。是时候正面处理Angular动画了。
设置动画
在制作动画之前, BrowserAnimationsModule
必须包含在根模块的imports数组中。它可以从@angular/platform-browser/animations
。此NgModule可确保动画适用于给定平台。本文假定每个示例的标准Web浏览器。
角度动画在@Component
元数据中声明。 @Component
装饰一个类,将其区分为Angular的一个组件。其元数据包含组件配置,包括animations: []
字段。此字段中的每个数组元素表示动画触发器( AnimationTriggerMetadata
)。
动画通过装饰器的元数据独占于其主机组件。动画只能在主机组件的模板中使用。动画不会继承到组件的子项。有一个简单的解决方法。
您始终可以创建一个导出数组的单独文件。任何组件类都可以从其主机文件的顶部导入该数组。然后,导入的数组标记将进入组件的动画元数据。对其动画元数据中需要相同数组的任何其他组件重复此过程。
内容投影允许您将动画应用于组件A的内容DOM(文档对象模型)。包装此内容的组件B DOM可以将内容投影到其自己的模板中。一旦它发生,组件A的动画不会否定。组件B通过内容投影结合A的动画。
好。您知道如何设置动画以及在何处声明动画。实施是下一步。
动画方法
角度动画使用一系列可从@angular/animations
导入的方法调用。 @Component
动画数组的每个元素都以单个方法开头。它的参数解析为一系列高阶方法调用。以下列表显示了用于构建Angular动画的一些方法。
trigger(selector: string, AnimationMetadata[])
返回AnimationTriggerMetadata
state(data: string, AnimationStyleMetadata, options?: object)
返回AnimationStateMetadata
style(CSSKeyValues: object)
返回AnimationStyleMetadata
animate(timing: string|number, AnimationStyleMetadata|KeyframesMetadata)
返回AnimationAnimateMetadata
transition(stateChange: string, AnimationMetadata|AnimationMetadata[], options?: object)
返回AnimationTransitionMetadata
trigger(selector:string,AnimationMetadata [])
trigger(...)
方法在动画数组中封装了一个动画元素。
方法的第一个参数selector: string
匹配[@selector]
成员属性。它的作用类似于组件模板中的属性指令。它实质上是通过属性选择器将动画元素连接到模板。
第二个参数是一个包含适用动画方法列表的数组。 trigger(...)
将它完全保存在一个阵列中。
state(data:string,AnimationStyleMetadata,options?:object)
state(...)
方法定义动画的最终状态。它在动画结束后将一个CSS属性列表应用于目标元素。这就是动画元素的CSS与动画的分辨率相匹配。
第一个参数匹配绑定到动画绑定的数据的值。也就是说,模板中[@selector]
绑定的值与state(...)
第一个参数匹配。数据的值决定了最终状态。值的改变决定了动画的手段(见transition(...)
)。
第二个参数承载适用于动画后元素的CSS样式。样式通过调用style(...)
传入,并将所需样式作为对象传递给其参数。
选项列表可选地占用第三个参数。除非另有说明,否则默认state(...)
选项应保持不变。
style(CSSKeyValues:object)
您可能已经在上一个列表中多次注意到AnimationStyleMetadata
。 style(...)
组件返回这种确切类型的元数据。无论何种CSS样式应用, style(...)
方法都必须调用。包含CSS样式的对象代表其参数。
当然,CSS中可动画的样式会延续到Angular style(...)
方法中。当然,使用Angular动画突然可能无法实现CSS。
animate(timing:string | number,AnimationStyleMetadata | AnimationKeyframesMetadata)
animate(...)
函数接受一个计时表达式作为其第一个参数。此参数会对方法的动画进行计时,调整和/或延迟。此参数接受数字或字符串表达式。
animate(...)
的第二个参数是保证动画的CSS属性。这采用了返回AnimationStyleMetadata
的style(...)
方法的形式。将animate(...)
视为启动动画的方法。
一系列关键帧也可以应用于第二个参数。关键帧是一个更高级的选项,本文稍后将对此进行说明。关键帧区分动画的各个部分。
animate(...)
可能不会收到第二个参数。在这种情况下,方法的动画计时仅适用于state(...)
方法中反映的CSS。触发器的state(...)
方法中的属性更改将设置动画。
转换(changExpr:string,AnimationMetadata | AnimationMetadata [],options?:object)
animate(...)
启动动画时动画transition(...)
确定动画启动的动画。
第一个参数包含一种独特的微语法形式。它表示发生的状态变化(或数据变化)。绑定到模板动画绑定的数据( [selector]="value"
)确定此表达式。即将发布的标题为“动画状态”的部分将进一步解释这一概念。
transition(...)
的第二个参数transition(...)
包括AnimationMetadata
(由animate(...)
返回)。该参数接受AnimationMetadata
数组或单个实例。
第一个参数的值与模板中绑定的数据的值匹配( [selector]="value"
)。如果发生完美匹配,则参数成功评估。然后第二个参数启动动画以响应第一个的成功。
选项列表可选地占用第三个参数。除非另有说明,否则默认transition(...)
选项应保持不变。
动画示例
import { Component, OnInit } from '@angular/core';
import { trigger, state, style, animate, transition } from '@angular/animations';
@Component({
selector: 'app-example',
template: `
<h3>Click the button to change its color!</h3>
<button (click)="toggleIsCorrect()" // event binding
[@toggleClick]="isGreen">Toggle Me!</button> // animation binding
`,
animations: [ // metadata array
trigger('toggleClick', [ // trigger block
state('true', style({ // final CSS following animation
backgroundColor: 'green'
})),
state('false', style({
backgroundColor: 'red'
})),
transition('true => false', animate('1000ms linear')), // animation timing
transition('false => true', animate('1000ms linear'))
])
] // end of trigger block
})
export class ExampleComponent {
isGreen: string = 'true';
toggleIsCorrect() {
this.isGreen = this.isGreen === 'true' ? 'false' : 'true'; // change in data-bound value
}
}
上面的示例在每次单击按钮时执行非常简单的颜色交换。当然,根据animate('1000ms linear')
,颜色以线性渐变快速过渡。动画通过将trigger(...)
的第一个参数与[@toggleClick]
动画绑定相匹配来绑定到按钮。
绑定绑定到组件类中isGreen
的值。此值确定由trigger(...)
块内的两个style(...)
方法设置的结果颜色。动画绑定是单向的,因此组件类中对isGreen
更改会通知模板绑定。也就是说,动画绑定[@toggleClick]
。
模板中的button元素也有一个绑定到它的click
事件。单击该按钮会导致isGreen
切换值。这会更改组件类数据。动画绑定会选中它并调用其匹配的trigger(...)
方法。 trigger(...)
位于组件元数据的动画数组中。触发器调用时会发生两件事。
第一次出现涉及两种state(...)
方法。 isGreen
的新值与state(...)
方法的第一个参数匹配。匹配后, style(...)
的CSS样式将应用于动画绑定的主机元素的最终状态。 `最终状态在所有动画后生效。
现在第二次出现。调用动画绑定的数据更改在两个transition(...)
方法之间进行比较。其中一个将数据更改与其第一个参数进行匹配。第一次按下按钮导致isGreen
从'true'变为'false'('true => false')。这意味着第一个transition(...)
方法激活其第二个参数。
对应于成功评估的transition(...)
方法的animate(...)
函数启动。此方法设置动画颜色渐变的持续时间以及淡入淡出的调步。动画执行,按钮渐变为红色。
点击按钮后,此过程可能会发生任意次。按钮的backgroundColor
将以线性淡入淡出在绿色和红色之间循环。
动画状态
transition(...)
微语法值得详细解决。 Angular通过评估此语法来确定动画及其时间。存在以下状态转换。他们模拟绑定到动画绑定的数据的更改。
'someValue' => 'anotherValue'
一个动画触发器,绑定数据从'someValue'变为'anotherValue'。
'anotherValue' => 'someValue'
动画触发器,绑定数据从“anotherValue”变为“someValue”。
'someValue' <=> 'anotherValue'
数据从'someValue`变为'anotherValue',反之亦然。
还存在void
和*
状态。 void
表示组件正在进入或离开DOM。这非常适合进入和退出动画。
'someValue' => void
:绑定数据的主机组件离开 DOMvoid => 'someValue'
:绑定数据的主机组件正在进入 DOM
*
表示通配符状态。通配符状态可以解释为“任何状态”。这包括void
以及对绑定数据的任何其他更改。
关键帧
本文介绍了为Angular应用程序设置动画的基础知识。高级动画技术与这些基础知识并存。将关键帧组合在一起就是这样一种技术。它的灵感来自@keyframes
CSS规则。如果您使用过CSS @keyframes
,那么您已经了解了Angular中的关键帧是如何工作的。它只是语法问题
keyframes(...)
方法从@angular/animations
导入。它传递给animate(...)
的第二个参数,而不是典型的AnimationStyleMetadata
。 keyframes(...)
方法接受一个参数作为AnimationStyleMetadata
的数组。这也可以称为style(...)
方法的数组。
动画的每个关键帧都在keyframes(...)
数组内。这些关键帧元素是支持offset
属性的style(...)
方法。 offset
表示动画持续时间中应包含其伴随样式属性的点。它的值从0(动画开始)到1(动画结束)。
import { Component } from '@angular/core';
import { trigger, state, style, animate, transition, keyframes } from '@angular/animations';
@Component({
selector: 'app-example',
styles: [
`.ball {
position: relative;
background-color: black;
border-radius: 50%;
top: 200px;
height: 25px;
width: 25px;
}`
],
template: `
<h3>Arcing Ball Animation</h3>
<button (click)="toggleBounce()">Arc the Ball!</button>
<div [@animateArc]="arc" class="ball"></div>
`,
animations: [
trigger('animateArc', [
state('true', style({
left: '400px',
top: '200px'
})),
state('false', style({
left: '0',
top: '200px'
})),
transition('false => true', animate('1000ms linear', keyframes([
style({ left: '0', top: '200px', offset: 0 }),
style({ left: '200px', top: '100px', offset: 0.50 }),
style({ left: '400px', top: '200px', offset: 1 })
]))),
transition('true => false', animate('1000ms linear', keyframes([
style({ left: '400px', top: '200px', offset: 0 }),
style({ left: '200px', top: '100px', offset: 0.50 }),
style({ left: '0', top: '200px', offset: 1 })
])))
])
]
})
export class ExampleComponent {
arc: string = 'false';
toggleBounce(){
this.arc = this.arc === 'false' ? 'true' : 'false';
}
}
与其他示例相比,上述示例的主要区别在于animate(...)
的第二个参数。它现在包含一个托管动画关键帧数组的关键keyframes(...)
方法。虽然动画本身也不同,但动画技术是相似的。
单击该按钮会使按钮在屏幕上呈弧形。弧根据keyframes(...)
方法的数组元素(关键帧)移动。在动画的中点( offset: 0.50
),球改变轨迹。当它继续穿过屏幕时,它下降到原始高度。再次单击该按钮可反转动画。
设置position: relative;
后, left
和top
是可动画的属性position: relative;
对于元素。 transform
属性可以执行类似的基于移动的动画。 transform
是一个广泛但完全可动画的属性。
在偏移0和1之间可以存在任意数量的关键帧。复杂的动画序列采用关键帧的形式。它们是Angular动画中的许多高级技术之一。
主机绑定动画
毫无疑问,您会遇到想要将动画附加到组件本身的HTML元素而不是组件模板中的元素的情况。这需要更多的努力,因为你不能只是进入模板HTML并在那里附加动画。相反,您必须导入HostBinding
并使用它。
此方案的最小代码如下所示。我会为上面的代码重复使用相同的动画条件以保持一致性,并且我不会显示任何实际的动画代码,因为您可以轻松地找到上面的代码。
import { Component, HostBinding } from '@angular/core';
@Component({
...
})
export class ExampleComponent {
@HostBinding('@animateArc') get arcAnimation() {
return this.arc;
}
}
动画主机组件背后的想法几乎与从模板中设置元素动画相同,唯一的区别是您无法访问要动画的元素。在声明HostBinding
,您仍然必须传递动画的名称( @animateArc
),并且仍然必须返回动画的当前状态( this.arc
)。函数的名称并不重要,因此arcAnimation
可以更改为任何内容,只要它不与组件上的现有属性名称冲突,它就可以正常工作。
结论
这涵盖了使用Angular进行动画制作的基础知识。 Angular使用Angular CLI可以非常轻松地设置动画。第一个动画入门只需要一个组件类。请记住,动画范围是组件的模板。如果计划在多个组件中使用过渡数组,请从单独的文件中导出过渡数组。
每个动画实用程序/方法都从@angular/animations
导出。他们共同努力,提供一个强大的CSS动画系统。除了本文可以涵盖的内容之外,还有更多方法。
现在您已了解基础知识,请随时浏览以下链接,了解有关Angular动画的更多信息。
更多Angular教程
学习更多Angular教程