sudut 2 ngIf dan transisi / animasi CSS


121

Saya ingin div meluncur dari kanan di sudut 2 menggunakan css.

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

Saya bekerja dengan baik jika saya hanya menggunakan [ngClass] untuk beralih kelas dan memanfaatkan opacity. Tetapi saya tidak ingin elemen itu dirender dari awal jadi saya "menyembunyikan" dengan ngIf terlebih dahulu, tetapi kemudian transisi tidak akan berfungsi.

.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;
}

Jawaban:


195

perbarui 4.1.0

Plunker

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

perbarui 2.1.0

Plunker

Untuk lebih jelasnya lihat Animasi di 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;
}

asli

*ngIfmenghapus elemen dari DOM saat ekspresi menjadi false. Anda tidak dapat melakukan transisi pada elemen yang tidak ada.

Gunakan sebagai gantinya hidden:

<div class="note" [ngClass]="{'transition':show}" [hidden]="!show">

2
Ya, tersembunyi hanya membuatnya tidak terlihat tetapi elemennya masih ada. *ngIfmenghapus seluruhnya dari DOM.
Günter Zöchbauer

1
Ini seperti display:none. Tidak ada display:hiddenAFAIK.
Günter Zöchbauer

1
@ GünterZöchbauer ya, opacity adalah akselerasi Hardware sehingga akan lebih cocok.
Ændri Domi

1
Lupakan. opacity tidak akan menghapus elemen dan akan tetap menutupi elemen di bawahnya, saya sarankan untuk menggunakan skala (0) yang akan mempengaruhi UI seperti display: none; tetapi dengan transisi yang bagus. Untuk menjawab OP dia dapat menggunakan animasi sudut angular.io/docs/ts/latest/guide/animations.html dengan transform: scale (0) pada status void
Ændri Domi

1
Item pemicu, gaya, animasi, dan transisi sekarang harus disertakan dari @ angular / animations. Jadi impor{ trigger, style, animate, transition } from '@angular/animations';
Joel Hernandez

137

Menurut dokumentasi sudut 2 terbaru, Anda dapat menganimasikan elemen "Masuk dan Keluar" (seperti di sudut 1).

Contoh animasi fade sederhana:

Dalam @Component yang relevan tambahkan:

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

Jangan lupa tambahkan impor

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

Elemen html komponen yang relevan akan terlihat seperti:

<div *ngIf="toggle" [@fadeInOut]>element</div>

Saya membuat contoh animasi slide dan fade di sini .

Penjelasan tentang 'void' dan '*':

  • void adalah keadaan kapan ngIf disetel ke salah (ini berlaku saat elemen tidak dilampirkan ke tampilan).
  • *- Ada banyak status animasi (baca lebih lanjut di dokumen). The *negara diutamakan atas semua dari mereka sebagai "wildcard" (dalam contoh saya ini adalah negara ketika ngIfdiatur ke true).

Pemberitahuan (diambil dari dokumen sudut):

Deklarasikan ekstra di dalam modul aplikasi, import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

Animasi sudut dibuat di atas API Animasi Web standar dan berjalan secara native di browser yang mendukungnya. Untuk browser lain, diperlukan polyfill. Ambil web-animations.min.js dari GitHub dan tambahkan ke halaman Anda.


2
Perlu mengimpor BrowserAnimationsModule untuk menggunakan animasi sudut. Jika saya tidak salah, modul animasi ditemukan di modul inti angular 2 sebelum dipindahkan ke modulnya sendiri, oleh karena itu mengapa Anda menemukan banyak contoh plunker tanpa impor. Berikut plnkr yang diperbarui dengan impor: Link
snaplemout

1
Saat menggunakan pendekatan seperti itu, leaveanimasi tidak berlangsung, karena komponen dihapus dari DOM *ngIfsebelum itu.
Slava Fomin II

4
Ini harus menjadi jawaban yang diterima, Ini benar-benar memberikan solusi kepada mereka yang ingin menggunakan ngIf dan bukan solusi lain.
Ovi Trif

17
    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: '*' }))
      ])
    ])

11

Solusi hanya CSS untuk browser modern

@keyframes slidein {
    0%   {margin-left:1500px;}
    100% {margin-left:0px;}
}
.note {
    animation-name: slidein;
    animation-duration: .9s;
    display: block;
}

Alternatif yang baik untuk masuk ke transisi khusus CSS. Digunakan ini sebagai solusi sementara untuk bermigrasi dari ng-enterpenggunaan kelas.
edmundo096

4

Salah satu caranya adalah dengan menggunakan penyetel untuk properti ngIf dan menyetel status sebagai bagian dari memperbarui nilai.

Contoh StackBlitz

fade.component.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;
      }
    }
  }

fade.component.html

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

example.component.css

:host {
  display: block;
}
.fade {
  opacity: 0;
}

3

Saya menggunakan angular 5 dan agar ngif bekerja untuk saya yang ada di ngfor, saya harus menggunakan animateChild dan di komponen detail pengguna saya menggunakan * ngIf = "user.expanded" untuk menampilkan menyembunyikan pengguna dan berfungsi untuk masuk meninggalkan

 <div *ngFor="let user of users" @flyInParent>
  <ly-user-detail [user]= "user" @flyIn></user-detail>
</div>

//the animation file


export const FLIP_TRANSITION = [ 
trigger('flyInParent', [
    transition(':enter, :leave', [
      query('@*', animateChild())
    ])
  ]),
  trigger('flyIn', [
    state('void', style({width: '100%', height: '100%'})),
    state('*', style({width: '100%', height: '100%'})),
    transition(':enter', [
      style({
        transform: 'translateY(100%)',
        position: 'fixed'
      }),
      animate('0.5s cubic-bezier(0.35, 0, 0.25, 1)', style({transform: 'translateY(0%)'}))
    ]),
    transition(':leave', [
      style({
        transform: 'translateY(0%)',
        position: 'fixed'
      }),
      animate('0.5s cubic-bezier(0.35, 0, 0.25, 1)', style({transform: 'translateY(100%)'}))
    ])
  ])
];

0

Dalam kasus saya, saya menyatakan animasi pada komponen yang salah secara tidak sengaja.

app.component.html

  <app-order-details *ngIf="orderDetails" [@fadeInOut] [orderDetails]="orderDetails">
  </app-order-details>

Animasi perlu dideklarasikan pada komponen tempat elemen digunakan dalam ( appComponent.ts). Saya menyatakan animasi OrderDetailsComponent.tssebagai gantinya.

Semoga bisa membantu seseorang melakukan kesalahan yang sama

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.