角度动画向上滑动内容菜单

时间:2018-11-06 11:36:05

标签: angular angular-animations

我正在努力使角度动画成为现实。 我找到了有关如何创建动画菜单的文章,因此我实现了它。到目前为止,这就是我所拥有的(我删除了与此问题无关的代码)

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;
}

可隐藏内容,但这并不是很好。 有没有人遇到过这个问题,并且知道如何解决?

1 个答案:

答案 0 :(得分:0)

我首先通过使我的 CSS 像这样来解决此问题:

filteredAndSortedData.map(contactDetail)

然后将动画更改为此:

: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;
    }
}

这样可以很好地折叠菜单,并同时隐藏内容。我不确定这将如何影响性能(将CSS与角度动画混合),但它是否有效。