我已经掌握了角度动画,并且正在尝试制作可正确设置动画的标题。 我一直在关注本教程:
https://netbasal.com/reactive-sticky-header-in-angular-12dbffb3f1d3
这可以帮助我创建标题,但是我不希望它完全执行他们正在做的事情,这就是为什么我需要一些帮助。 首先,向下滚动页面时;我不希望整个标题消失。相反,我希望它缩小到10px左右;当我向上滚动时,我希望它达到60像素; 我将动画更改为此:
trigger('toggle', [
state(
VisibilityState.Hidden,
style({ opacity: 1, height: '10px' })
),
state(
VisibilityState.Visible,
style({ opacity: 1, height: '60px' })
),
transition('* => *', animate('200ms ease-in'))
])
可扩展使用。 我的模板中有一些内容,当标头包含时,内容不会收缩。 我的标头组件CSS如下所示:
:host {
position: fixed;
top: 0;
width: 100%;
text-align: center; // TODO: only for testing, remove later
background-color: indigo; // TODO: only for testing, remove later
}
HTML如下所示:
<div class="header">
<p>This is the header</p>
</div>
因此,这个问题的第一部分是,如何在压缩菜单时隐藏内容(无论是什么内容)?我敢肯定那是容易的部分:)
第二部分是我要添加一个新的事件/动画。当您将鼠标悬停在压缩形式的菜单上时,我希望它可以扩展到其原始大小(就像您向上滚动页面一样)。 这对我来说很难,希望您能给我任何帮助。
*更新*
我设法使第二部分开始工作。 我将HTML更改为此:
<div class="header" (mouseenter) ="mouseEnter() " (mouseleave) ="mouseLeave()">
<p>This is the header</p>
</div>
并向该组件添加了一个新属性和2个新方法:
private wasVisible = this.isVisible;
mouseEnter() {
this.wasVisible = this.isVisible === true;
this.isVisible = true;
}
mouseLeave() {
this.isVisible = this.wasVisible === true;
}
因此,当我将鼠标悬停在组件上时,如果它已经可见,它将保持该状态;当我离开组件时,它将重置为进入组件之前的状态。 如果压缩了该组件,它将对其进行解压缩,而当我们移出该组件时,它将使其恢复压缩状态。
现在我只需要弄清楚如何对内容进行排序。
答案 0 :(得分:1)
隐藏内容:
将成员变量isVisible
公开,以便您可以在视图中使用它,然后使用*ngIf="isVisible"
隐藏内容。
悬停:
向组件添加两个带有@HostListener("mouseenter")
和@HostListener("mouseleave")
的方法,像这样实现它们:
@HostListener("mouseenter")
onMouseEnter() {
this.isVisible = true;
}
@HostListener("mouseleave")
onMouseLeave() {
this.isVisible = false;
}
答案 1 :(得分:0)
所以,我唯一想到的方法是将一个类应用于该元素。所以我修改了切换方法:
@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;
}
这使我可以像这样添加修改组件的CSS:
:host {
position: fixed;
top: 0;
width: 100%;
height: 60px;
text-align: center; // TODO: only for testing, remove later
background-color: indigo; // TODO: only for testing, remove later
.header {
visibility: visible;
opacity: 1;
transition: visibility .2s, opacity .2s linear;
}
&.collapsed .header {
visibility: hidden;
opacity: 0;
}
}
现在,我不确定CSS是否可以像Angular动画一样平滑地渲染,但这是我到目前为止发现的唯一解决方案。
作为参考,这里是整个组件:
import { Component, AfterViewInit, HostBinding, HostListener, ElementRef, Renderer2 } from '@angular/core';
import { animate, state, style, transition, trigger } from '@angular/animations';
import { distinctUntilChanged, filter, map, pairwise, share, throttleTime } from 'rxjs/operators';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/fromEvent';
enum VisibilityState {
Visible = 'visible',
Hidden = 'hidden'
}
enum Direction {
Up = 'Up',
Down = 'Down'
}
@Component({
selector: 'piiick-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 {
private isVisible = true;
private wasVisible = this.isVisible;
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.wasVisible = this.isVisible === true;
this.isVisible = true;
}
@HostListener('mouseleave')
mouseLeave() {
this.isVisible = this.wasVisible === true;
}
ngAfterViewInit() {
const scroll$ = Observable.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));
}
}