Angular 4 - 当 div 进入视口时如何触发动画? [英] Angular 4 - how to trigger an animation when a div comes into the viewport?

查看:30
本文介绍了Angular 4 - 当 div 进入视口时如何触发动画?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在使用 Angular 4 构建一个新站点,我正在尝试重新创建一个效果,当一个 div 变得可见时(当你向下滚动屏幕时)然后可以触发一个角度动画来滑动div 的形式.

I've been building a new site using Angular 4 and i'm trying to re-create a effect where when a div becomes visible (when you scroll down the screen) then that can then trigger a angular animation to slide the div in form the sides.

过去我已经能够在 Angular 4 之外使用 jQuery 做到这一点,但我想尝试使用原生 Angular 4 动画来创建相同的效果.

I've been able to do this in the past using jQuery outside of Angular 4 but i want to try and create the same effect using native Angular 4 animations.

任何人都可以就如何在 div 进入视图时触发动画提供建议(即在进入视口时向下滚动到页面的下部?).我已经编写了幻灯片动画,但我不知道如何在 div 稍后在视口可见时通过滚动触发它.

Can anyone offer me advice on how to trigger an animation when a div comes into view (i.e. scrolled down to lower part of the page as it enters the viewport?). I have written the slide animations already but i don't know how to trigger that with a scroll when a div becomes visible at a later date to the view port.

谢谢大家!

推荐答案

我创建了一个指令,一旦元素完全在视图中或者它的上边缘到达视图的上边缘,它就会发出一个事件.

I've created a directive that emits an event as soon as the element is either completely within view or it's upper edge has reached view's upper edge.

这是一个 plunker:https://embed.plnkr.co/mlez1dXjR87FNBHXq1YM/

Here's a plunker: https://embed.plnkr.co/mlez1dXjR87FNBHXq1YM/

它是这样使用的:

 <div (appear)="onAppear()">...</div>

指令如下:

import {
  ElementRef, Output, Directive, AfterViewInit, OnDestroy, EventEmitter
} from '@angular/core';
import {Observable} from 'rxjs/Observable';
import {Subscription} from 'rxjs/Subscription';
import 'rxjs/add/observable/fromEvent';
import 'rxjs/add/operator/startWith';

@Directive({
  selector: '[appear]'
})
export class AppearDirective implements AfterViewInit, OnDestroy {
  @Output()
  appear: EventEmitter<void>;

  elementPos: number;
  elementHeight: number;

  scrollPos: number;
  windowHeight: number;

  subscriptionScroll: Subscription;
  subscriptionResize: Subscription;

  constructor(private element: ElementRef){
    this.appear = new EventEmitter<void>();
  }

  saveDimensions() {
    this.elementPos = this.getOffsetTop(this.element.nativeElement);
    this.elementHeight = this.element.nativeElement.offsetHeight;
    this.windowHeight = window.innerHeight;
  }
  saveScrollPos() {
    this.scrollPos = window.scrollY;
  }
  getOffsetTop(element: any){
    let offsetTop = element.offsetTop || 0;
    if(element.offsetParent){
      offsetTop += this.getOffsetTop(element.offsetParent);
    }
    return offsetTop;
  }
  checkVisibility(){
    if(this.isVisible()){
      // double check dimensions (due to async loaded contents, e.g. images)
      this.saveDimensions();
      if(this.isVisible()){
        this.unsubscribe();
        this.appear.emit();
      }
    }
  }
  isVisible(){
    return this.scrollPos >= this.elementPos || (this.scrollPos + this.windowHeight) >= (this.elementPos + this.elementHeight);
  }

  subscribe(){
    this.subscriptionScroll = Observable.fromEvent(window, 'scroll').startWith(null)
      .subscribe(() => {
        this.saveScrollPos();
        this.checkVisibility();
      });
    this.subscriptionResize = Observable.fromEvent(window, 'resize').startWith(null)
      .subscribe(() => {
        this.saveDimensions();
        this.checkVisibility();
      });
  }
  unsubscribe(){
    if(this.subscriptionScroll){
      this.subscriptionScroll.unsubscribe();
    }
    if(this.subscriptionResize){
      this.subscriptionResize.unsubscribe();
    }
  }

  ngAfterViewInit(){
    this.subscribe();
  }
  ngOnDestroy(){
    this.unsubscribe();
  }
}

这篇关于Angular 4 - 当 div 进入视口时如何触发动画?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆