多重动画触发器
在很多时候,在一个组件中可能会定义不止一个动画,并且这些动画的触发器附着在不同的元素上,从而就免不了的就是元素之间的父子关系所对应的动画,这种元素之间的父子关系的动画运行方式会受到元素关系的影响。
父子动画
在Angular中,每次触发的动画中,都会先触发父元素上动画,子元素上的动画就不会触发。为了触发子元素上的动画,父元素必须要查询到包含子动画的每一个元素,然后使用animateChild()函数来运行这些子动画。
利用 @.disabled 来控制某些父元素下面的子元素动画禁用与否
现在用一个button去控制前面飞入动画的禁用与否,修改模版文件为:
<nz-divider [nzText]="'飞入飞出动画'"></nz-divider>
<nz-row>
<button nz-button (click)="handleInOut()">按钮</button>
<button nz-button (click)="handleDisabled()">改变禁用动画</button>
禁用的状态:{{isDisabled}}
</nz-row>
<nz-row>
<nz-form-control nzSpan="10" nzOffset="7" [@.disabled]="isDisabled">
<div style="text-align: center;background: red" *ngIf="isInOut" [@fly]="isInOut?'flyIn':'void'">
飞入飞出动画~
</div>
</nz-form-control>
</nz-row>
增加属性isDisabled来控制动画禁用与否,并将利用一个按钮的点击事件来改变禁用的状态。故修改类文件为:
import {Component, OnInit} from '@angular/core';
import {trigger, state, style, animate, transition} from '@angular/animations';
@Component({
selector: 'app-animation-demo',
templateUrl: './animation-demo.component.html',
styleUrls: ['./animation-demo.component.less'],
animations: [
// 定义动画的触发器放在 animations 元数据属性中
trigger('stateChange', [
state('isYellow', style(
{
height: '200px',
width: '200px',
opacity: 1,
backgroundColor: 'yellow'
}
)),
state('isGreen', style(
{
height: '100px',
width: '100px',
opacity: 0.5,
backgroundColor: 'green'
}
)),
state('isRed', style(
{
height: '150px',
width: '150px',
opacity: 0.5,
backgroundColor: 'red'
}
)),
transition('isYellow <=> isGreen', animate('1s')),
transition('* => isRed', animate('0.5s', style({opacity: '*'}))),
transition('* => *', animate('5s')),
]),
trigger('fly', [
state('flyIn', style({
transform: 'translateX(0)',
color: 'blue',
})),
transition('void => *', [
style({
transform: 'translateX(-100%)',
color: 'yellow'
}),
animate('2s')
]),
transition('* => void', [
animate('2s', style({
transform: 'translateX(100%)',
color: 'red'
})),
])
])
],
})
export class AnimationDemoComponent implements OnInit {
public isChange = false;
public isInOut = false;
public isDisabled = false;
constructor() {
}
ngOnInit() {
}
public handleChange(state): void {
this.isChange = state;
}
public handleInOut() {
this.isInOut = !this.isInOut;
}
public handleDisabled() {
this.isDisabled = !this.isDisabled;
}
}
然后保存,刷新页面后看到如下:
当isDisabled属性为false的时候,子元素
上的飞入动画,正常运行,然后点击改变禁用动画按钮,将isDisabled属性设为true的时候,在此运行动画的时候,会发现,此刻的动画已经不能运行了。
此时的父元素的disabled动画就起作用了。它将子元素上的动画给禁用了。
禁用所有动画
由于在Angular项目中,默认情况下,appComponent是所有组件的父组件,所以禁用整个项目中的动画,只在appComponent中将.disabled绑定上就可以了。
@Component({
selector: 'app-root',
templateUrl: 'app.component.html',
styleUrls: ['app.component.css'],
animations: [
slideInAnimation
]
})
export class AppComponent {
@HostBinding('@.disabled')
public animationsDisabled = false;
}
在端到端的测试中,禁用所有项目中的动画非常有用。