我正在使用折叠:https ://ng-bootstrap.github.io/#/components/collapse
但是,它没有动画;甚至不在演示站点上。我应该如何实现这个?
我正在使用折叠:https ://ng-bootstrap.github.io/#/components/collapse
但是,它没有动画;甚至不在演示站点上。我应该如何实现这个?
我认为这是一个很好的方法,它既可以用于显示也可以用于折叠:(尽管它不再需要 ng-bootstrap)
模板.html:
<button (click)="isCollapsed = !isCollapsed">Toggle</button> <p [@smoothCollapse]="isCollapsed?'initial':'final'"> your data here </p>
.
组件.ts:
import { trigger, state, style, animate, transition } from '@angular/animations'; @Component({ selector: 'app-my-component', templateUrl: './template.html', styleUrls: ['./style.scss'], animations: [ trigger('smoothCollapse', [ state('initial', style({ height:'0', overflow:'hidden', opacity:'0' })), state('final', style({ overflow:'hidden', opacity:'1' })), transition('initial=>final', animate('750ms')), transition('final=>initial', animate('750ms')) ]), ] }) export class MyComponent ...
细节:
[ngbCollapse]="isCollapsed"
,<p>
否则它会破坏所有动画。我们不需要它,因为我们将高度设置为 0希望它有所帮助,我花了一天时间:P
因为他们使用“display:none”来隐藏和“display:block”来显示元素,所以你不能应用“transition”CSS属性。
所以,强制显示块,管理高度和不透明度来切换隐藏/显示:
.collapse, .collapse.in {
display: block !important;
transition: all .25s ease-in-out;
}
.collapse {
opacity: 0;
height: 0;
}
.collapse.in {
opacity: 1;
height: 100%;
}
有了基本的过渡和不透明度/高度,它似乎更平滑。
您可以使用关键帧制作自己的动画并应用于 .collapse.in 以获得更好的切换隐藏/显示体验。
然后,如果您在项目中使用 Angular 2,您可以切换到 ng2-bootstrap:http: //valor-software.com/ng2-bootstrap/
在您的组件中,您可以添加如下内容:
animations: [
trigger('expandCollapse', [
state('open', style({height: '100%', opacity: 1})),
state('closed', style({height: 0, opacity: 0})),
transition('* => *', [animate('100ms')])
]),
]
<div [ngbCollapse]="isCollapsed" [@expandCollapse]="isCollapsed ? 'closed' : 'open'"> ... </div>
在此处查看更多详细信息https://angular.io/guide/animations#animating-a-simple-transition
我只使用引导类创建了一个指令,它只使用角度动画执行相同的原始引导效果,检查一下!
指令代码
import {Directive, ElementRef, HostBinding, Input, OnChanges, OnInit, SimpleChanges} from '@angular/core';
import {animate, AnimationBuilder, AnimationPlayer, keyframes, style} from '@angular/animations';
@Directive({
selector: '[appCollapseAnimated]'
})
export class CollapseAnimatedDirective implements OnChanges, OnInit {
private static readonly SHOW_STYLE = 'show';
private static readonly COLLAPSING = 'collapsing';
@Input('appCollapseAnimated')
collapsed = true;
@Input()
skipClosingAnimation = false;
@HostBinding('class.collapse')
private readonly addCollapseClass = true;
private currentEffect: AnimationPlayer;
private _closeEffect: AnimationPlayer;
private _openEffect: AnimationPlayer;
constructor(private el: ElementRef,
private builder: AnimationBuilder) {
}
ngOnInit(): void {
if (!this.collapsed) {
this.getClassList().add(CollapseAnimatedDirective.SHOW_STYLE);
}
}
private get openEffect(): AnimationPlayer {
if (!this._openEffect) {
this._openEffect = this.builder.build(animate('500ms', keyframes([
style({height: '0'}),
style({height: '*'}),
]))).create(this.el.nativeElement);
}
this._openEffect.onDone(() => this.effectDone());
return this._openEffect;
}
private get closeEffect(): AnimationPlayer {
if (!this._closeEffect) {
this._closeEffect = this.builder.build(animate('500ms', keyframes([
style({height: '*'}),
style({height: '0'}),
]))).create(this.el.nativeElement);
}
this._closeEffect.onDone(() => this.effectDone());
return this._closeEffect;
}
private effectDone() {
if (this.collapsed) {
this.getClassList().remove(CollapseAnimatedDirective.SHOW_STYLE);
}
this.getClassList().remove(CollapseAnimatedDirective.COLLAPSING);
if (this.currentEffect) {
this.currentEffect.reset();
this.currentEffect = null;
}
}
ngOnChanges(changes: SimpleChanges): void {
if (changes.collapsed && !changes.collapsed.firstChange) {
if (changes.collapsed.previousValue === true && changes.collapsed.currentValue === false) {
this.startOpening();
}
if (changes.collapsed.previousValue === false && changes.collapsed.currentValue === true) {
this.startClosing();
}
}
}
private startOpening(): void {
this.getClassList().add(CollapseAnimatedDirective.SHOW_STYLE);
const effect = this.openEffect;
this.playEffect(effect);
}
private getClassList() {
const nativeElement = this.el.nativeElement as HTMLElement;
return nativeElement.classList;
}
private startClosing(): void {
const effect = this.closeEffect;
if (this.skipClosingAnimation) {
this.effectDone();
} else {
this.playEffect(effect);
}
}
private playEffect(effect: AnimationPlayer) {
if (!this.currentEffect) {
this.getClassList().add(CollapseAnimatedDirective.COLLAPSING);
this.currentEffect = effect;
this.currentEffect.play();
}
}
}
在您的模板中使用它:
<button class="btn btn-primary" (click)="collapsed = !collapsed">
Toggle
</button>
<div [appCollapseAnimated]="collapsed" class="beautiful-div border border-secondary mt-5">
this should collapse with the default bootstrap behaviour
</div>