angular 2 ngIf y CSS transición / animación
Quiero que un div se deslice desde la derecha en angular 2 usando css.
<div class="note" [ngClass]="{'transition':show}" *ngIf="show">
<p> Notes</p>
</div>
<button class="btn btn-default" (click)="toggle(show)">Toggle</button>
Funciona bien si solo uso [ngClass] para alternar clase y utilizar opacidad. Pero li no quiere que ese elemento se renderice desde el principio, así que lo "escondo" con ngIf primero, pero luego la transición no funcionará.
.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;
}
6 answers
Actualización 4.1.0
Plunker
Véase también https://github.com/angular/angular/blob/master/CHANGELOG.md#400-rc1-2017-02-24
Actualización 2.1.0
Plunker
Para más detalles, ver Animaciones en 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;
}
Original
*ngIf
elimina el elemento del DOM cuando la expresión se convierte en false
. No se puede tener una transición en un no existente elemento.
Use en su lugar hidden
:
<div class="note" [ngClass]="{'transition':show}" [hidden]="!show">
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-26 15:49:35
Según la última documentación de angular 2 puede animar elementos" Entrando y saliendo " (como en angular 1).
Ejemplo de animación de fundido simple:
En el componente @relevante agrega:
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}))
])
])
]
No se olvide de añadir importaciones
import {style, state, animate, transition, trigger} from '@angular/animations';
El elemento html del componente relevante debería tener el siguiente aspecto:
<div *ngIf="toggle" [@fadeInOut]>element</div>
Construí un ejemplo de animación de diapositivas y fundido aquí.
Explicación sobre 'void ' y'*':
-
void
es el estado cuandongIf
se establece en false (se aplica cuando el elemento no se adjunta a una vista). -
*
- Puede haber muchos estados de animación (lea más en los documentos). El estado*
tiene prioridad sobre todos ellos como un "comodín" (en mi ejemplo este es el estado cuandongIf
se establece entrue
).
Aviso (tomado de angular docs):
Las animaciones angulares se construyen sobre la API estándar de animaciones web y se ejecuta de forma nativa en navegadores que lo admiten. Para otros navegadores, un se requiere polyfill. Agarra animaciones web.min.js de GitHub y añadir a tu página.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-28 13:07:28
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: '*' }))
])
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-06 14:54:11
Solución única de CSS para navegadores modernos
@keyframes slidein {
0% {margin-left:1500px;}
100% {margin-left:0px;}
}
.note {
animation-name: slidein;
animation-duration: .9s;
display: block;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-07 08:49:45
Estoy usando angular 5 y para que un ngif funcione para mí que está en un ngfor, tuve que usar animateChild y en el componente user-detail utilicé el *ngIf="user.expanded " para mostrar ocultar el usuario y funcionó para ingresar una salida
<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%)'}))
])
])
];
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-03 18:37:45
Una forma es usar un setter para la propiedad ngIf y establecer el estado como parte de la actualización del valor. Cuando se establece la propiedad a true DetectChanges () necesita ser llamado para asegurarse de que el elemento se añade de nuevo al dom antes de que el estado de la animación se cambia.
Ejemplo.componente.ts
import { Component, AnimationTransitionEvent, OnInit } from '@angular/core';
import { trigger, state, style, animate, transition } from '@angular/animations';
@Component({
selector: 'example',
templateUrl: `./example.component.html`,
styleUrls: [`./example.component.css`],
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')
])
])
]
})
export class ExampleComponent implements OnInit {
state: string;
private _showButton: boolean;
get showButton() {
return this._showButton;
}
set showButton(val: boolean) {
if (val) {
this._showButton = true;
this.state = 'visible';
} else {
this.state = 'hidden';
}
}
constructor() {
}
ngOnInit() {
this.showButton = true;
}
animationDone(event: AnimationTransitionEvent) {
if (event.fromState === 'visible' && event.toState === 'hidden') {
this._showButton = false;
}
}
log() {
console.log('clicked');
}
}
Ejemplo.componente.html
<div>
<p>animation state: {{state}}</p>
<p>showButton: {{showButton}}</p>
<button (click)="showButton = !showButton">toggle</button>
</div>
<button class="animation-target" *ngIf="showButton" [@state]="state" (@state.done)="animationDone($event)" (click)="log()" >animation target</button>
Ejemplo.componente.css
.animation-target {
background: orange;
height: 150px;
width: 150px;
cursor: pointer;
opacity: 0;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-22 12:52:01