[英]angular 2 ngIf and CSS transition/animation
I want a div to slide in from the right in angular 2 using css.我想要一个 div 使用 css 从 angular 2 的右侧滑入。
<div class="note" [ngClass]="{'transition':show}" *ngIf="show">
<p> Notes</p>
</div>
<button class="btn btn-default" (click)="toggle(show)">Toggle</button>
I works fine if i only use [ngClass] to toggle class and utilise opacity.如果我只使用 [ngClass] 来切换类并利用不透明度,我工作得很好。 But li don't want that element to be rendered from the beginning so I "hide" it with ngIf first, but then the transition wont't work.
但是 li 不希望该元素从一开始就呈现,所以我首先用 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;
}
update 4.1.0更新 4.1.0
See also https://github.com/angular/angular/blob/master/CHANGELOG.md#400-rc1-2017-02-24另见https://github.com/angular/angular/blob/master/CHANGELOG.md#400-rc1-2017-02-24
update 2.1.0更新 2.1.0
For more details see Animations at angular.io有关更多详细信息,请参阅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
removes the element from the DOM when the expression becomes false
. *ngIf
在表达式变为false
时从 DOM 中删除元素。 You can't have a transition on a non-existing element.您不能对不存在的元素进行过渡。
Use instead hidden
:改为使用
hidden
:
<div class="note" [ngClass]="{'transition':show}" [hidden]="!show">
According to the latest angular 2 documentation you can animate "Entering and Leaving" elements (like in angular 1).根据最新的angular 2 文档,您可以为“进入和离开”元素设置动画(如 angular 1)。
Example of simple fade animation:简单的淡入淡出动画示例:
In relevant @Component add:在相关的@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}))
])
])
]
Do not forget to add imports不要忘记添加导入
import {style, state, animate, transition, trigger} from '@angular/animations';
The relevant component's html's element should look like:相关组件的 html 元素应如下所示:
<div *ngIf="toggle" [@fadeInOut]>element</div>
I built example of slide and fade animation here .我在这里构建了幻灯片和淡入淡出动画的示例。
Explanation on 'void' and '*':说明在“无效”和“*”:
void
is the state when ngIf
is set to false (it applies when the element is not attached to a view). void
是ngIf
设置为 false 时的状态(当元素未附加到视图时适用)。*
- There can be many animation states (read more in docs). *
- 可以有许多动画状态(在文档中阅读更多内容)。 The *
state takes precedence over all of them as a "wildcard" (in my example this is the state when ngIf
is set to true
). *
状态作为“通配符”优先于所有这些(在我的示例中,这是ngIf
设置为true
时的状态)。 Notice (taken from angular docs):注意(取自 angular 文档):
Extra declare inside the app module, import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
在 app 模块中额外声明,
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
Angular animations are built on top of the standard Web Animations API and run natively on browsers that support it.
Angular 动画建立在标准的 Web Animations API 之上,并在支持它的浏览器上本地运行。 For other browsers, a polyfill is required.
对于其他浏览器,需要一个 polyfill。 Grab web-animations.min.js from GitHub and add it to your page.
从 GitHub 获取 web-animations.min.js 并将其添加到您的页面。
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: '*' }))
])
])
CSS only solution for modern browsers现代浏览器的 CSS 唯一解决方案
@keyframes slidein {
0% {margin-left:1500px;}
100% {margin-left:0px;}
}
.note {
animation-name: slidein;
animation-duration: .9s;
display: block;
}
One way is to use a setter for the ngIf property and set the state as part of updating the value.一种方法是对 ngIf 属性使用 setter 并将状态设置为更新值的一部分。
StackBlitz example StackBlitz 示例
fade.component.ts淡入淡出.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淡入淡出.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例子.component.css
:host {
display: block;
}
.fade {
opacity: 0;
}
Am using angular 5 and for an ngif to work for me that is in a ngfor, I had to use animateChild and in the user-detail component I used the *ngIf="user.expanded" to show hide user and it worked for entering a leaving我正在使用 angular 5 并且在 ngfor 中为我工作的 ngif,我必须使用 animateChild 并且在用户详细信息组件中我使用 *ngIf="user.expanded" 来显示隐藏用户并且它可以用于输入离开
<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%)'}))
])
])
];
In my case I declared the animation on the wrong component by mistake.就我而言,我错误地在错误的组件上声明了动画。
app.component.html应用程序组件.html
<app-order-details *ngIf="orderDetails" [@fadeInOut] [orderDetails]="orderDetails">
</app-order-details>
The animation needs to be declared on the component where the element is used in ( appComponent.ts
).动画需要在使用元素的组件上声明 (
appComponent.ts
)。 I was declaring the animation on OrderDetailsComponent.ts
instead.我改为在
OrderDetailsComponent.ts
上声明动画。
Hopefully it will help someone making the same mistake希望它能帮助犯同样错误的人
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.