Angular 9 анимаций во вьюпорте - PullRequest
0 голосов
/ 05 августа 2020

Я хочу добавить в свой проект анимацию, особенно для <section> и некоторых заголовков ( h1, h2, h3 ). Я попробовал несколько вариантов; один с использованием анимации Angular и один с использованием animate. css.

Оба они работают должным образом, но теперь я хотел бы только анимировать, когда <section> в данный момент находится в поле зрения (впервые).

Сначала я попробовал https://www.npmjs.com/package/ng2-animate-on-scroll, но не смог заставить его работать. Даже с animate.s css.

Затем я попробовал: https://scrollrevealjs.org/, используя https://www.npmjs.com/package/ngx-scrollreveal. Это сработало, но я смог заставить его использовать только cubic-bezier(0.25, 0.1, 0.25, 1). Больше ничего не работало, и я хотел бы иметь все функции, доступные в animate. css или, по крайней мере, fadeInUp , fadeInLeft и fadeInRight

Затем я попробовал: https://github.com/Epenance/ngx-animate-in#readme, который снова работает и пока что является лучшим, потому что использует angular анимацию, но не поддерживается в * 1050. * вообще, так что это бесполезно.

Итак, мой вопрос: есть ли лучший способ сделать это? В идеале я хотел бы использовать анимацию angular при прокрутке контента в поле зрения, и я хотел бы контролировать, какую анимацию использовать. Возможно ли это, и было ли сделано или использовано что-нибудь, что могло бы помочь?

1 Ответ

0 голосов
/ 06 августа 2020

В конце я использовал старый код, который я объединил с директивой ngx-animate, чтобы получить следующее:

import { Directive, ElementRef, HostListener, Input } from '@angular/core';
import {
  AnimationBuilder,
  AnimationFactory,
  AnimationMetadata,
  AnimationPlayer,
  style,
  animate,
} from '@angular/animations';

@Directive({
  selector: '[sxpAnimate]',
})
export class AnimateDirective {
  @Input() animateInAnimation: AnimationMetadata | AnimationMetadata[];
  @HostListener('window:scroll', ['$event']) // for window scroll events
  onScroll() {
    this.animate();
  }

  private animating: boolean;
  private player: AnimationPlayer;
  private defaults: any = {
    offset: 0,
  };

  constructor(
    private el: ElementRef,
    private animationBuilder: AnimationBuilder
  ) {}

  ngOnInit() {
    this.initialize();
    this.animate();
  }

  private initialize(): void {
    let animation: AnimationFactory;

    if (
      this.animateInAnimation !== null &&
      this.animateInAnimation !== undefined
    ) {
      animation = this.animationBuilder.build(this.animateInAnimation);
    } else {
      animation = this.animationBuilder.build([
        style({ opacity: 0, transform: 'translateX(-100px)' }),
        animate(
          '1200ms cubic-bezier(0.35, 0, 0.25, 1)',
          style({ opacity: 1, transform: 'translateX(0)' })
        ),
      ]);
    }

    this.player = animation.create(this.el.nativeElement);
    this.player.init();
  }

  private animate(): void {
    const inView = this.isInViewport();

    if (!inView) this.animating = false;
    if (!inView || this.animating) return;

    this.player.play();
    this.animating = true;
  }

  private isInViewport(): boolean {
    const bounding = this.el.nativeElement.getBoundingClientRect();

    let top =
      bounding.top -
      (window.innerHeight || document.documentElement.clientHeight);
    let bottom = bounding.top + bounding.height + this.defaults.offset;

    return top < 0 && bottom > 0;
  }
}

Кажется, работает так, как я хочу; так что я буду опираться на это :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...