Angular2:你如何运行 2个并行动画?
Angular2: How do you run 2 animations in parallel?
我有一个 expands/shrinks 的容器。该容器内有一个元素,它应该在容器扩展时淡入,在容器收缩时淡出。
我的问题
- 当容器展开时,两个元素的动画都起作用。
- 当容器收缩时,只有容器动画起作用。
- 如果我删除容器展开动画,那么淡入淡出 in/out 动画会按预期工作。
如何让所有动画在两个 expand/shrink 条件下并行执行?
注意ngIf的使用。这是故意的,因为它会在动画序列结束时破坏元素。
这是我目前状态的一个plunkr:
https://embed.plnkr.co/TXYoGf9QpErWmlRvQF9Z/
组件class:
export class App {
expanded = true;
toggleExpandedState() {
this.expanded = !this.expanded;
}
constructor() {
}
}
模板:
<div class="container" [@expansionTrigger]="expanded">
<div class="constant-item"></div>
<div class="fade-item" [@stateAnimation] *ngIf="expanded"></div>
</div>
<button (click)="toggleExpandedState()">Toggle Fade</button>
和组件动画:
trigger('expansionTrigger', [
state('1', style({
width: '250px'
})),
state('0', style({
width: '160px'
})),
transition('0 => 1', animate('200ms ease-in')),
transition('1 => 0', animate('200ms ease-out'))
]),
trigger('stateAnimation', [
transition(':enter', [
style({
opacity: 0
}),
animate('200ms 350ms ease-in', style({
opacity: 1
}))
]),
transition(':leave', [
style({
opacity: 1
})
animate('1s', style({
opacity: 0
}))
])
])
这是您需要做的:
plnkr 在这里:https://plnkr.co/edit/AQEVh3GGc31ivQZMp223?p=preview
删除 *ngIf="expanded"
使用 [@stateAnimation]="expanded"
将您的 stateAnimate
触发器替换为:
trigger('stateAnimation', [
state('1', style({ opacity: 0 })),
state('0', style({opacity: 1})),
transition('0 => 1', animate('200ms ease-in')),
transition('1 => 0', animate('200ms ease-out'))
])
完整代码如下:
//our root app component
import {Component, NgModule, VERSION,
Output,
trigger,
state,
style,
transition,
animate,
} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
@Component({
selector: 'my-app',
template: `
<div class="container" [@expansionTrigger]="expanded">
<div class="constant-item"></div>
<div class="fade-item" [@stateAnimation]="expanded"></div>
</div>
<button (click)="toggleExpandedState()">Toggle Fade</button>
`,
animations: [
trigger('expansionTrigger', [
state('1', style({ width: '250px' })),
state('0', style({width:'160px'})),
transition('0 => 1', animate('200ms ease-in')),
transition('1 => 0', animate('200ms ease-out'))
]),
trigger('stateAnimation', [
state('1', style({ opacity: 0 })),
state('0', style({opacity: 1})),
transition('0 => 1', animate('200ms ease-in')),
transition('1 => 0', animate('200ms ease-out'))
])
]
})
export class App {
expanded = true;
toggleExpandedState() {
this.expanded = !this.expanded;
}
constructor() {
}
}
@NgModule({
imports: [ BrowserModule, BrowserAnimationsModule ],
declarations: [ App ],
bootstrap: [ App ]
})
export class AppModule {}
希望避免其他人的挫败感,看起来这是 Angular 4.
的错误
目前 Github 上有两个未解决的问题似乎密切相关:
https://github.com/angular/angular/issues/15798
https://github.com/angular/angular/issues/15753
更新
根据 github 问题,动画错误将无法像在 Angular2 中那样修复。而是引入了 query()
和 animateChild()
。新的动画功能从 4.2.0-rc2 开始可用。
总结:
组件定义
@Component({
selector: 'my-app',
template: `
<div>
<h2>Hello {{name}}</h2>
<button (click)="toggle()">Toggle</button>
<div *ngIf="show" @ngIfAnimation>
<h3 @easeInOut>I'm inside ngIf</h3>
</div>
</div>
`,
animations: [
trigger('ngIfAnimation', [
transition(':enter, :leave', [
query('@*', animateChild())
])
])
trigger('easeInOut', [
transition('void => *', [
style({
opacity: 0
}),
animate("1s ease-in-out", style({
opacity: 1
}))
]),
transition('* => void', [
style({
opacity: 1
}),
animate("1s ease-in-out", style({
opacity: 0
}))
])
])
]]
})
export class App {
name:string;
show:boolean = false;
constructor() {
this.name = `Angular! v${VERSION.full}`
}
toggle() {
this.show = !this.show;
}
}
这里有一个可用的示例:https://embed.plnkr.co/RJgAunJfibBKNFt0DCZS/
我有一个 expands/shrinks 的容器。该容器内有一个元素,它应该在容器扩展时淡入,在容器收缩时淡出。
我的问题
- 当容器展开时,两个元素的动画都起作用。
- 当容器收缩时,只有容器动画起作用。
- 如果我删除容器展开动画,那么淡入淡出 in/out 动画会按预期工作。
如何让所有动画在两个 expand/shrink 条件下并行执行?
注意ngIf的使用。这是故意的,因为它会在动画序列结束时破坏元素。
这是我目前状态的一个plunkr: https://embed.plnkr.co/TXYoGf9QpErWmlRvQF9Z/
组件class:
export class App {
expanded = true;
toggleExpandedState() {
this.expanded = !this.expanded;
}
constructor() {
}
}
模板:
<div class="container" [@expansionTrigger]="expanded">
<div class="constant-item"></div>
<div class="fade-item" [@stateAnimation] *ngIf="expanded"></div>
</div>
<button (click)="toggleExpandedState()">Toggle Fade</button>
和组件动画:
trigger('expansionTrigger', [
state('1', style({
width: '250px'
})),
state('0', style({
width: '160px'
})),
transition('0 => 1', animate('200ms ease-in')),
transition('1 => 0', animate('200ms ease-out'))
]),
trigger('stateAnimation', [
transition(':enter', [
style({
opacity: 0
}),
animate('200ms 350ms ease-in', style({
opacity: 1
}))
]),
transition(':leave', [
style({
opacity: 1
})
animate('1s', style({
opacity: 0
}))
])
])
这是您需要做的:
plnkr 在这里:https://plnkr.co/edit/AQEVh3GGc31ivQZMp223?p=preview
删除 *ngIf="expanded"
使用 [@stateAnimation]="expanded"
将您的 stateAnimate
触发器替换为:
trigger('stateAnimation', [
state('1', style({ opacity: 0 })),
state('0', style({opacity: 1})),
transition('0 => 1', animate('200ms ease-in')),
transition('1 => 0', animate('200ms ease-out'))
])
完整代码如下:
//our root app component
import {Component, NgModule, VERSION,
Output,
trigger,
state,
style,
transition,
animate,
} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
@Component({
selector: 'my-app',
template: `
<div class="container" [@expansionTrigger]="expanded">
<div class="constant-item"></div>
<div class="fade-item" [@stateAnimation]="expanded"></div>
</div>
<button (click)="toggleExpandedState()">Toggle Fade</button>
`,
animations: [
trigger('expansionTrigger', [
state('1', style({ width: '250px' })),
state('0', style({width:'160px'})),
transition('0 => 1', animate('200ms ease-in')),
transition('1 => 0', animate('200ms ease-out'))
]),
trigger('stateAnimation', [
state('1', style({ opacity: 0 })),
state('0', style({opacity: 1})),
transition('0 => 1', animate('200ms ease-in')),
transition('1 => 0', animate('200ms ease-out'))
])
]
})
export class App {
expanded = true;
toggleExpandedState() {
this.expanded = !this.expanded;
}
constructor() {
}
}
@NgModule({
imports: [ BrowserModule, BrowserAnimationsModule ],
declarations: [ App ],
bootstrap: [ App ]
})
export class AppModule {}
希望避免其他人的挫败感,看起来这是 Angular 4.
的错误目前 Github 上有两个未解决的问题似乎密切相关:
https://github.com/angular/angular/issues/15798
https://github.com/angular/angular/issues/15753
更新
根据 github 问题,动画错误将无法像在 Angular2 中那样修复。而是引入了 query()
和 animateChild()
。新的动画功能从 4.2.0-rc2 开始可用。
总结:
组件定义
@Component({
selector: 'my-app',
template: `
<div>
<h2>Hello {{name}}</h2>
<button (click)="toggle()">Toggle</button>
<div *ngIf="show" @ngIfAnimation>
<h3 @easeInOut>I'm inside ngIf</h3>
</div>
</div>
`,
animations: [
trigger('ngIfAnimation', [
transition(':enter, :leave', [
query('@*', animateChild())
])
])
trigger('easeInOut', [
transition('void => *', [
style({
opacity: 0
}),
animate("1s ease-in-out", style({
opacity: 1
}))
]),
transition('* => void', [
style({
opacity: 1
}),
animate("1s ease-in-out", style({
opacity: 0
}))
])
])
]]
})
export class App {
name:string;
show:boolean = false;
constructor() {
this.name = `Angular! v${VERSION.full}`
}
toggle() {
this.show = !this.show;
}
}
这里有一个可用的示例:https://embed.plnkr.co/RJgAunJfibBKNFt0DCZS/