Angular 动画向上滑动内容菜单
Angular animation slide up content menu
我正在努力了解 angular 动画。
我找到了一篇关于如何创建动画菜单的文章,所以我实现了它。这就是我目前所拥有的(我已经删除了与这个问题无关的代码)
import { Component, AfterViewInit, HostBinding, HostListener, ElementRef, Renderer2, OnInit } from '@angular/core';
import { animate, state, style, transition, trigger } from '@angular/animations';
import { distinctUntilChanged, filter, map, pairwise, share, throttleTime } from 'rxjs/operators';
import { fromEvent } from 'rxjs';
enum VisibilityState {
Visible = 'visible',
Hidden = 'hidden'
}
enum Direction {
Up = 'Up',
Down = 'Down'
}
@Component({
selector: 'pyb-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.scss'],
animations: [
trigger('toggle', [
state(
VisibilityState.Hidden,
style({ height: '10px' })
),
state(
VisibilityState.Visible,
style("*")
),
transition('* => *', animate('200ms ease-in'))
])
]
})
export class HeaderComponent implements AfterViewInit, OnInit {
private isVisible: boolean = true;
constructor(
private renderer: Renderer2,
private element: ElementRef
) { }
@HostBinding('@toggle')
get toggle(): VisibilityState {
if (this.isVisible) {
this.renderer.removeClass(this.element.nativeElement, 'collapsed');
}
else {
this.renderer.addClass(this.element.nativeElement, 'collapsed');
}
return this.isVisible ? VisibilityState.Visible : VisibilityState.Hidden;
}
@HostListener('mouseenter')
mouseEnter() {
this.isVisible = true;
}
@HostListener('mouseleave')
mouseLeave() {
this.isVisible = false;
}
ngOnInit() {
}
ngAfterViewInit() {
const scroll$ = fromEvent(window, 'scroll').pipe(
throttleTime(10),
map(() => window.pageYOffset),
pairwise(),
map(([y1, y2]): Direction => (y2 < y1 ? Direction.Up : Direction.Down)),
distinctUntilChanged(),
share()
);
const scrollUp$ = scroll$.pipe(
filter(direction => direction === Direction.Up)
);
const scrollDown = scroll$.pipe(
filter(direction => direction === Direction.Down)
);
scrollUp$.subscribe(() => {
this.isVisible = true
});
scrollDown.subscribe(() => {
this.isVisible = false;
});
}
}
现在,如果模板是这样的:
<div class="header" #header>
</div>
而 CSS 是这样的:
:host {
height: $header-height;
background-color: $clouds;
color: $midnight;
position: fixed;
top: 0;
width: 100%;
z-index: 1000;
}
似乎一切正常。
但是,一旦我添加内容,它就无法正常工作。
我的模板实际上是这样的:
<div class="header" #header>
<div class="container">
<div class="row">
<div class="col" *ngIf="retailers && count && !displayMatches">
<p class="float-left"><b>{{ count }}</b> {{ category }} available at </p>
<pyb-text-slider [textArray]="retailers"></pyb-text-slider>
</div>
<div class="col" *ngIf="matches && displayMatches">
<span [ngSwitch]="matches.length">
<p *ngSwitchCase="0"><b>{{ matches.length }}</b> {{ category }}</p>
<p *ngSwitchDefault><b>{{ matches.length }}</b> {{ category }} from <b>{{ matches[0].price }}</b></p>
</span>
<pyb-matches></pyb-matches>
</div>
</div>
</div>
</div>
问题是,内容不会随菜单一起折叠。
我不得不添加一些 CSS:
.header {
visibility: visible;
opacity: 1;
transition: visibility .2s, opacity .2s linear;
padding: 12px 0;
}
&.collapsed .header {
visibility: hidden;
opacity: 0;
}
它隐藏了内容,但这并不是很好。
有没有人以前遇到过这个问题并且知道如何解决它?
我通过首先使我的 CSS 像这样解决了这个问题:
:host {
height: $header-height;
background-color: $clouds;
color: $midnight;
position: fixed;
top: 0;
width: 100%;
z-index: 1000;
transform-origin: top;
.header {
transition: visibility .2s, opacity .2s linear;
visibility: visible;
opacity: 1;
padding: 12px 0;
}
&.collapsed .header {
visibility: hidden;
opacity: 0;
}
}
然后将我的动画更改为:
animations: [
trigger('toggle', [
state(
VisibilityState.Hidden,
style({ transform: 'scaleY(0.2)' })
),
state(
VisibilityState.Visible,
style({ transform: 'scaleY(1)' })
),
transition('* => *', animate('200ms ease-in'))
])
]
这很好地折叠了菜单,同时隐藏了内容。我不确定这将如何影响性能(将 CSS 与 angular 动画混合)但它有效。
我正在努力了解 angular 动画。 我找到了一篇关于如何创建动画菜单的文章,所以我实现了它。这就是我目前所拥有的(我已经删除了与这个问题无关的代码)
import { Component, AfterViewInit, HostBinding, HostListener, ElementRef, Renderer2, OnInit } from '@angular/core';
import { animate, state, style, transition, trigger } from '@angular/animations';
import { distinctUntilChanged, filter, map, pairwise, share, throttleTime } from 'rxjs/operators';
import { fromEvent } from 'rxjs';
enum VisibilityState {
Visible = 'visible',
Hidden = 'hidden'
}
enum Direction {
Up = 'Up',
Down = 'Down'
}
@Component({
selector: 'pyb-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.scss'],
animations: [
trigger('toggle', [
state(
VisibilityState.Hidden,
style({ height: '10px' })
),
state(
VisibilityState.Visible,
style("*")
),
transition('* => *', animate('200ms ease-in'))
])
]
})
export class HeaderComponent implements AfterViewInit, OnInit {
private isVisible: boolean = true;
constructor(
private renderer: Renderer2,
private element: ElementRef
) { }
@HostBinding('@toggle')
get toggle(): VisibilityState {
if (this.isVisible) {
this.renderer.removeClass(this.element.nativeElement, 'collapsed');
}
else {
this.renderer.addClass(this.element.nativeElement, 'collapsed');
}
return this.isVisible ? VisibilityState.Visible : VisibilityState.Hidden;
}
@HostListener('mouseenter')
mouseEnter() {
this.isVisible = true;
}
@HostListener('mouseleave')
mouseLeave() {
this.isVisible = false;
}
ngOnInit() {
}
ngAfterViewInit() {
const scroll$ = fromEvent(window, 'scroll').pipe(
throttleTime(10),
map(() => window.pageYOffset),
pairwise(),
map(([y1, y2]): Direction => (y2 < y1 ? Direction.Up : Direction.Down)),
distinctUntilChanged(),
share()
);
const scrollUp$ = scroll$.pipe(
filter(direction => direction === Direction.Up)
);
const scrollDown = scroll$.pipe(
filter(direction => direction === Direction.Down)
);
scrollUp$.subscribe(() => {
this.isVisible = true
});
scrollDown.subscribe(() => {
this.isVisible = false;
});
}
}
现在,如果模板是这样的:
<div class="header" #header>
</div>
而 CSS 是这样的:
:host {
height: $header-height;
background-color: $clouds;
color: $midnight;
position: fixed;
top: 0;
width: 100%;
z-index: 1000;
}
似乎一切正常。 但是,一旦我添加内容,它就无法正常工作。 我的模板实际上是这样的:
<div class="header" #header>
<div class="container">
<div class="row">
<div class="col" *ngIf="retailers && count && !displayMatches">
<p class="float-left"><b>{{ count }}</b> {{ category }} available at </p>
<pyb-text-slider [textArray]="retailers"></pyb-text-slider>
</div>
<div class="col" *ngIf="matches && displayMatches">
<span [ngSwitch]="matches.length">
<p *ngSwitchCase="0"><b>{{ matches.length }}</b> {{ category }}</p>
<p *ngSwitchDefault><b>{{ matches.length }}</b> {{ category }} from <b>{{ matches[0].price }}</b></p>
</span>
<pyb-matches></pyb-matches>
</div>
</div>
</div>
</div>
问题是,内容不会随菜单一起折叠。 我不得不添加一些 CSS:
.header {
visibility: visible;
opacity: 1;
transition: visibility .2s, opacity .2s linear;
padding: 12px 0;
}
&.collapsed .header {
visibility: hidden;
opacity: 0;
}
它隐藏了内容,但这并不是很好。 有没有人以前遇到过这个问题并且知道如何解决它?
我通过首先使我的 CSS 像这样解决了这个问题:
:host {
height: $header-height;
background-color: $clouds;
color: $midnight;
position: fixed;
top: 0;
width: 100%;
z-index: 1000;
transform-origin: top;
.header {
transition: visibility .2s, opacity .2s linear;
visibility: visible;
opacity: 1;
padding: 12px 0;
}
&.collapsed .header {
visibility: hidden;
opacity: 0;
}
}
然后将我的动画更改为:
animations: [
trigger('toggle', [
state(
VisibilityState.Hidden,
style({ transform: 'scaleY(0.2)' })
),
state(
VisibilityState.Visible,
style({ transform: 'scaleY(1)' })
),
transition('* => *', animate('200ms ease-in'))
])
]
这很好地折叠了菜单,同时隐藏了内容。我不确定这将如何影响性能(将 CSS 与 angular 动画混合)但它有效。