Angular2的动画系统赋予了制作各种动画效果的能力,致力于构建出与原生CSS动画性能相同的动画。
Angular2的动画主要是和@Component
结合在了一起。
animations元数据属性在定义@Component装饰。就像template元数据属性!这样就可以让动画逻辑与其应用代码紧紧集成在一起,这让动画可以更容易的出发与控制。
使用要点
Angular2的动画是使用模型驱动的方式在两个状态之间进行转换,是由状态和状态之间的转场效果所定义的。
动画被定义在
@Component
元数据中。需要定义一个动画触发器(triggerName),在模板中使用[@triggerName]语法来把它附加到一个或多个元素上去。
triggerName设置成表达式,不同的状态,来定义动画状态。如果状态发生改变。state
state中具体定义的是每个状态的最终样式。一旦元素转场到这个状态,那么样式就会留在这个状态,并且会一直保持着。从这个意义上讲,这里其实并不只是定义动画,而是在定义该元素在不同状态时应该具有的样式。如果把状态内联在
transition
中就只会在转场中有保留样式,转场完成后,就不会保留了。动画中可以动的属性和单位
由于Angular的动画支持基于Web Animations标准的,所以也能支持浏览器认为可以参与动画的任何属性。这些属性包括位置(position)、大小(size)、变换(transform)、颜色(color)、边框(border)等很多属性。W3C维护着 一个“可动”属性列表。
“可动”属性列表: 一般就是长度、颜色、可见性
Property Name | Type |
---|---|
background-color | as color |
background-position | as repeatable list of simple list of length, percentage, or calc |
border-bottom-color | as color |
border-bottom-width | as length |
border-left-color | as color |
border-left-width | as length |
border-right-color | as color |
border-right-width | as length |
border-spacing | as simple list of length |
border-top-color | as color |
border-top-width | as length |
bottom | as length, percentage, or calc |
clip | as rectangle |
color | as color |
font-size | as length |
font-weight | as font weight |
height | as length, percentage, or calc |
left | as length, percentage, or calc |
letter-spacing | as length |
line-height | as either number or length |
margin-bottom | as length |
margin-left | as length |
margin-right | as length |
margin-top | as length |
max-height | as length, percentage, or calc |
max-width | as length, percentage, or calc |
min-height | as length, percentage, or calc |
min-width | as length, percentage, or calc |
opacity | as number |
outline-color | as color |
outline-width | as length |
padding-bottom | as length |
padding-left | as length |
padding-right | as length |
padding-top | as length |
right | as length, percentage, or calc |
text-indent | as length, percentage, or calc |
text-shadow | as shadow list |
top | as length, percentage, or calc |
vertical-align | as length |
visibility | as visibility |
width | as length, percentage, or calc |
word-spacing | as length |
z-index | as integer |
e.g.
这个一个淡入淡出的文本内容。
import { Component, OnChanges, Input, trigger, state, style, animate, transition } from '@angular/core';
@Component({
selector: 'my-fader',
template: `
Can you see me? I should fade in or out...
`,
styleUrls: ['./my-fader.css'],
animations: [ // 动画的内容
trigger('visibilityChanged', [
// state 控制不同的状态下对应的不同的样式
state('shown' , style({ opacity: 1, transform: 'scale(1.0)' })),
state('hidden', style({ opacity: 0, transform: 'scale(0.0)' })),
// transition 控制状态到状态以什么样的方式来进行转换
transition('shown => hidden', animate('600ms')),
transition('hidden => shown', animate('300ms')),
])
]
})
export class MyFaderComponent implements OnChanges{
visibility = 'shown'; // 避免ngOnChanges()并降低代码复杂度
@Input() isVisible : boolean = true;
ngOnChanges() {
this.visibility = this.isVisible ? 'shown' : 'hidden';
}
}
将动画改为关键帧,动画效果为下面:
animations: [
trigger('visibilityChanged', [
transition('shown => hidden', animate('600ms', keyframes([
style({opacity: 0, transform: 'translateX(-100%)', offset: 0}),
style({opacity: 1, transform: 'translateX(15px)', offset: 0.3}),
style({opacity: 1, transform: 'translateX(0)', offset: 1.0}),
]))),
transition('hidden => shown', animate('300ms', keyframes([
style({opacity: 1, transform: 'translateX(0)', offset: 0}),
style({opacity: 1, transform: 'translateX(-15px)', offset: 0.7}),
style({opacity: 0, transform: 'translateX(100%)', offset: 1.0})
]))),
])
]
小知识点
*
通配符
(通配符)状态匹配任何动画状态。当定义那些不需要管当前处于什么状态的样式及转场时,这很有用。void状态
有一种叫做void的特殊状态,它可以应用在任何动画中。它表示元素没有被附加到视图。这种情况可能是由于它尚未被添加进来或者已经被移除了。 void状态在定义“进场”和“离场”的动画时会非常有用。-
动画时间线
对每一个动画转场效果,有三种时间线属性可以调整:持续时间(duration)、延迟(delay)和缓动(easing)函数。它们被合并到了一个单独的转场时间线字符串- 持续时间
持续时间控制动画从开始到结束要花多长时间。可以用三种方式定义持续时间:- 作为一个普通数字,以毫秒为单位,如:100
- 作为一个字符串,以毫秒为单位,如:'100ms'
- 作为一个字符串,以秒为单位,如:'0.1s'
- 延迟
延迟控制的是在动画已经触发但尚未真正开始转场之前要等待多久。可以把它添加到字符串中的持续时间后面,它的选项格式也跟持续时间是一样的:
等待100毫秒,然后运行200毫秒:'0.2s 100ms'。
- 持续时间
-
缓动函数
缓动函数用于控制动画在运行期间如何加速和减速。比如:使用ease-in
。
·函数意味着动画开始时相对缓慢,然后在进行中逐步加速。可以通过在这个字符串中的持续时间和延迟后面添加第三个值来控制使用哪个缓动函数(如果没有定义延迟就作为第二个值)。- 等待100毫秒,然后运行200毫秒,并且带缓动:'0.2s 100ms ease-out'
- 运行200毫秒,并且带缓动:'0.2s ease-in-out'
-
基于关键帧(Keyframes)的多阶段动画
类似于CSS3中的动画。
通过定义动画的关键帧,可以把两组样式之间的简单转场,升级成一种更复杂的动画,它会在转场期间经历一个或多个中间样式。
每个关键帧都可以被指定一个偏移量,用来定义该关键帧将被用在动画期间的哪个时间点。偏移量是一个介于0(表示动画起点)和1(表示动画终点)之间的数组。
animations: [
trigger('flyInOut', [
state('in', style({transform: 'translateX(0)'})),
transition('void => *', [
animate(300, keyframes([ // 回弹的效果
style({opacity: 0, transform: 'translateX(-100%)', offset: 0}),
style({opacity: 1, transform: 'translateX(15px)', offset: 0.3}),
style({opacity: 1, transform: 'translateX(0)', offset: 1.0})
]))
]),
transition('* => void', [
animate(300, keyframes([
style({opacity: 1, transform: 'translateX(0)', offset: 0}),
style({opacity: 1, transform: 'translateX(-15px)', offset: 0.7}),
style({opacity: 0, transform: 'translateX(100%)', offset: 1.0})
]))
])
])
]
- 动画回调
当动画开始和结束时,会触发一个回调。
这些回调接收一个AnimationTransitionEvent参数,它包含一些有用的属性,例如fromState,toState和totalTime。
无论动画是否实际执行过,那些回调都会触发。
template: `
-
{{hero.name}}
`,
参考文档
- (Angular Animations - Foundation Concepts)[https://blog.thoughtram.io/angular/2016/09/16/angular-2-animation-important-concepts.html]
- (angular2官网-animations)[https://angular.cn/guide/animations]
- (css3-动画)[http://www.w3school.com.cn/css3/css3_animation.asp]