Angular2:你如何并行运行2个动画?

时间:2017-04-02 16:42:34

标签: angular typescript angular-ng-if

我有一个扩展/收缩的容器。容器内部有一个元素,当容器膨胀时应该淡入,当容器收缩时应该淡出。

我的问题

  • 当容器展开时,两个元素的动画都有效。
  • 当容器缩小时,只有容器动画才能生效。
  • 如果我删除容器扩展动画,则淡入/淡出动画将按预期工作。

如何在扩展/收缩条件下并行执行所有动画?

注意使用 ngIf 。这是故意的,因为它会破坏动画序列末尾的元素。

这是我当前状态的一个傻瓜: https://embed.plnkr.co/TXYoGf9QpErWmlRvQF9Z/

组件类:

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
      }))
    ])
  ])

2 个答案:

答案 0 :(得分:2)

这是您需要做的事情:

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 {}

答案 1 :(得分:2)

为了拯救他人沮丧,看起来这是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/