Skip to content

Instantly share code, notes, and snippets.

@realtomaszkula
Last active June 16, 2020 09:48
Show Gist options
  • Save realtomaszkula/08cc5632f3427d41254068d322807c51 to your computer and use it in GitHub Desktop.
Save realtomaszkula/08cc5632f3427d41254068d322807c51 to your computer and use it in GitHub Desktop.
enum VisibilityState {
Visible = 'visible',
Hidden = 'hidden'
}
enum Direction {
Up = 'Up',
Down = 'Down'
}
@Component({
selector: 'app-sticky-header',
template: `<ng-content></ng-content>`,
styles: [
`
:host {
position: fixed;
top: 0;
width: 100%;
}
`
],
animations: [
trigger('toggle', [
state(
VisibilityState.Hidden,
style({ opacity: 0, transform: 'translateY(-100%)' })
),
state(
VisibilityState.Visible,
style({ opacity: 1, transform: 'translateY(0)' })
),
transition('* => *', animate('200ms ease-in'))
])
]
})
export class StickyHeaderComponent implements AfterViewInit {
private isVisible = true;
@HostBinding('@toggle')
get toggle(): VisibilityState {
return this.isVisible ? VisibilityState.Visible : VisibilityState.Hidden;
}
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));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment