File

src/app/modules/core/directives/stickyheader.directive.ts

Example

Metadata

selector [appStickyHeader]

Constructor

constructor(builder: AnimationBuilder, el: any, zone: NgZone, cdr: ChangeDetectorRef)

Methods

Private fadeIn
fadeIn()
Returns: AnimationMetadata[]
Private fadeOut
fadeOut()
Returns: AnimationMetadata[]

Properties

isOffline
isOffline: boolean
player
player: AnimationPlayer
Public unsubscribe
unsubscribe: Subject<void>
import { environment } from '@sunbird/environment';
import { animate, AnimationBuilder, AnimationMetadata, AnimationPlayer, style } from '@angular/animations';

import { AfterViewInit, Directive, ElementRef, Inject, OnDestroy, NgZone, ChangeDetectorRef, } from '@angular/core';
import { fromEvent, Subject } from 'rxjs';
import { distinctUntilChanged, filter, map, pairwise, share, throttleTime, takeUntil, tap } from 'rxjs/operators';

enum Direction {
  Up = 'Up',
  Down = 'Down',
  None = 'None'
}

/** @dynamic */
@Directive({
  selector: '[appStickyHeader]'
})
export class StickyHeaderDirective implements AfterViewInit, OnDestroy {
  player: AnimationPlayer;
  public unsubscribe = new Subject<void>();
  isOffline: boolean = environment.isOffline;

  set show(show: boolean) {
    if (this.player) {
      this.player.destroy();
    }

    const metadata = show ? this.fadeIn() : this.fadeOut();

    const factory = this.builder.build(metadata);
    const player = factory.create(this.el.nativeElement);

    player.play();
  }

  constructor(private builder: AnimationBuilder, private el: ElementRef, private zone: NgZone,
    private cdr: ChangeDetectorRef) {}

  private fadeIn(): AnimationMetadata[] {
    return [style({ opacity: 0}), animate('400ms ease-in', style({ opacity: 1, transform: 'translateY(0)'}))];
  }

  private fadeOut(): AnimationMetadata[] {
    return [style({ opacity: '*' }), animate('400ms ease-in', style({ opacity: 0, transform: 'translateY(-100%)' }))];
  }

  ngAfterViewInit() {
    if (this.isOffline) {
      return false;
    }
    this.zone.runOutsideAngular(() => {
    const scroll$ = fromEvent(window, 'scroll').pipe(
      throttleTime(10),
      map( (window1) => window.pageYOffset),
      pairwise(),
      map(([y1, y2]): Direction => {
        return (y2 < y1 ? ((y1 < 160 || y2 < 160) ? Direction.Up : Direction.None) : (y2 > 160 ? Direction.Down : Direction.None));
      }),
      distinctUntilChanged(),
      share(),
      takeUntil(this.unsubscribe));
    const goingUp$ = scroll$.pipe(filter(direction => direction === Direction.Up), takeUntil(this.unsubscribe));

    const goingDown$ = scroll$.pipe(filter(direction => direction === Direction.Down), takeUntil(this.unsubscribe));

    goingUp$.subscribe(() => {
      this.show = true;
      this.cdr.detectChanges();
    });
    goingDown$.subscribe(() => {
      this.show = false;
      this.cdr.detectChanges();
    });
  });
  }

  ngOnDestroy() {
    this.unsubscribe.next();
    this.unsubscribe.complete();
  }
}


results matching ""

    No results matching ""