角度2 ngIf和CSS过渡/动画

Han*_*Che 107 css angular angular-animations

我希望div使用css从角度2向右滑入.

  <div class="note" [ngClass]="{'transition':show}" *ngIf="show">
    <p> Notes</p>
  </div>
  <button class="btn btn-default" (click)="toggle(show)">Toggle</button>
Run Code Online (Sandbox Code Playgroud)

如果我只使用[ngClass]切换类并使用不透明度,我工作正常.但是李不希望从一开始就渲染这个元素,所以我首先用ngIf"隐藏"它,但是转换不会起作用.

.transition{
  -webkit-transition: opacity 1000ms ease-in-out,margin-left 500ms ease-in-out;
  -moz-transition: opacity 1000ms ease-in-out,margin-left 500ms ease-in-out;
  -ms-transition: opacity 1000ms ease-in-out,margin-left 500ms ease-in-out ;
  -o-transition: opacity 1000ms ease-in-out,margin-left 500ms ease-in-out;
  transition: opacity 1000ms ease-in-out,margin-left 500ms ease-in-out;
  margin-left: 1500px;
  width: 200px;
  opacity: 0;
}

.transition{
  opacity: 100;
  margin-left: 0;
}
Run Code Online (Sandbox Code Playgroud)

Gün*_*uer 180

更新4.1.0

Plunker

另见https://github.com/angular/angular/blob/master/CHANGELOG.md#400-rc1-2017-02-24

更新2.1.0

Plunker

有关更多详细信息,请参阅angular.io上的动画

import { trigger, style, animate, transition } from '@angular/animations';

@Component({
  selector: 'my-app',
  animations: [
    trigger(
      'enterAnimation', [
        transition(':enter', [
          style({transform: 'translateX(100%)', opacity: 0}),
          animate('500ms', style({transform: 'translateX(0)', opacity: 1}))
        ]),
        transition(':leave', [
          style({transform: 'translateX(0)', opacity: 1}),
          animate('500ms', style({transform: 'translateX(100%)', opacity: 0}))
        ])
      ]
    )
  ],
  template: `
    <button (click)="show = !show">toggle show ({{show}})</button>

    <div *ngIf="show" [@enterAnimation]>xxx</div>
  `
})
export class App {
  show:boolean = false;
}
Run Code Online (Sandbox Code Playgroud)

原版的

*ngIf表达式变为时从DOM中删除元素false.您不能在不存在的元素上进行转换.

改为使用hidden:

<div class="note" [ngClass]="{'transition':show}" [hidden]="!show">
Run Code Online (Sandbox Code Playgroud)

  • 是的,隐藏仅使其不可见,但该元素仍然存在。* ngIf`将其从DOM中完全删除。 (2认同)
  • @GünterZöchbauer 是的,不透明度是硬件加速的,所以它会更适合。 (2认同)
  • 现在应该从 @angular/animations 中包含触发器、样式、动画和过渡项。所以从'@angular/animations'导入`{ trigger, style, animate, transition };` (2认同)

Asa*_*nel 121

根据最新的angular 2文档, 您可以为"Entering and Leaving"元素设置动画(如角度1).

简单淡入淡出动画的示例:

在相关的@Component中添加:

animations: [
  trigger('fadeInOut', [
    transition(':enter', [   // :enter is alias to 'void => *'
      style({opacity:0}),
      animate(500, style({opacity:1})) 
    ]),
    transition(':leave', [   // :leave is alias to '* => void'
      animate(500, style({opacity:0})) 
    ])
  ])
]
Run Code Online (Sandbox Code Playgroud)

不要忘记添加导入

import {style, state, animate, transition, trigger} from '@angular/animations';
Run Code Online (Sandbox Code Playgroud)

相关组件的html元素应如下所示:

<div *ngIf="toggle" [@fadeInOut]>element</div>
Run Code Online (Sandbox Code Playgroud)

在这里建立了幻灯片和淡入淡出动画的 示例.

说明在"无效"和"*":

  • voidngIf设置为false 的状态(当元素未附加到视图时适用).
  • * - 可以有许多动画状态(在文档中阅读更多).该*状态优先于所有的人都为"通配符"(在我的例子,这是状态时,ngIf设置为true).

注意(取自角度文档):

角度动画构建于标准Web动画API之上,并在支持它的浏览器上本机运行.对于其他浏览器,需要填充.从GitHub获取web-animations.min.js并将其添加到您的页面.

  • 这应该是公认的答案,它实际上为那些想要使用ngIf而不是其他解决方法的人提供了解决方案. (4认同)
  • 需要导入BrowserAnimationsModule以使用角度动画。如果我没看错的话,动画模块是在angular 2的核心模块中找到的,然后再移至其自己的模块,因此为什么您会发现许多没有导入的插件示例。这是带有导入内容的更新的plnkr:[链接](https://plnkr.co/edit/2FaCZeruyu6EQn5t3GWY?p=preview) (2认同)
  • 当使用这种方法时,不会发生“leave”动画,因为在此之前组件已被“*ngIf”从 DOM 中删除。 (2认同)

kra*_*s88 14

    trigger('slideIn', [
      state('*', style({ 'overflow-y': 'hidden' })),
      state('void', style({ 'overflow-y': 'hidden' })),
      transition('* => void', [
        style({ height: '*' }),
        animate(250, style({ height: 0 }))
      ]),
      transition('void => *', [
        style({ height: '0' }),
        animate(250, style({ height: '*' }))
      ])
    ])
Run Code Online (Sandbox Code Playgroud)


Mik*_*ike 10

现代浏览器的CSS唯一解决方案

@keyframes slidein {
    0%   {margin-left:1500px;}
    100% {margin-left:0px;}
}
.note {
    animation-name: slidein;
    animation-duration: .9s;
    display: block;
}
Run Code Online (Sandbox Code Playgroud)


Jay*_*ase 5

一种方法是使用 ngIf 属性的 setter 并将状态设置为更新值的一部分。

StackBlitz 示例

淡入淡出组件.ts

 import {
    animate,
    AnimationEvent,
    state,
    style,
    transition,
    trigger
  } from '@angular/animations';
  import { ChangeDetectionStrategy, Component, Input } from '@angular/core';

  export type FadeState = 'visible' | 'hidden';

  @Component({
    selector: 'app-fade',
    templateUrl: './fade.component.html',
    styleUrls: ['./fade.component.scss'],
    animations: [
      trigger('state', [
        state(
          'visible',
          style({
            opacity: '1'
          })
        ),
        state(
          'hidden',
          style({
            opacity: '0'
          })
        ),
        transition('* => visible', [animate('500ms ease-out')]),
        transition('visible => hidden', [animate('500ms ease-out')])
      ])
    ],
    changeDetection: ChangeDetectionStrategy.OnPush
  })
  export class FadeComponent {
    state: FadeState;
    // tslint:disable-next-line: variable-name
    private _show: boolean;
    get show() {
      return this._show;
    }
    @Input()
    set show(value: boolean) {
      if (value) {
        this._show = value;
        this.state = 'visible';
      } else {
        this.state = 'hidden';
      }
    }

    animationDone(event: AnimationEvent) {
      if (event.fromState === 'visible' && event.toState === 'hidden') {
        this._show = false;
      }
    }
  }
Run Code Online (Sandbox Code Playgroud)

fade.component.html

 <div
    *ngIf="show"
    class="fade"
    [@state]="state"
    (@state.done)="animationDone($event)"
  >
    <button mat-raised-button color="primary">test</button>
  </div>
Run Code Online (Sandbox Code Playgroud)

示例.组件.css

:host {
  display: block;
}
.fade {
  opacity: 0;
}
Run Code Online (Sandbox Code Playgroud)