Angular 4 - 当 div 进入视口时如何触发动画? [英] Angular 4 - how to trigger an animation when a div comes into the viewport?
问题描述
我一直在使用 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屋!