我花了几天时间试图弄清楚这一点。作为一个新手,我尝试了很多东西,但都没有奏效。最后,我有一个解决方案,所以我会在这里发布。
有两个步骤:
- 当事物出现时动画化。
- 滚动时显示内容。
第 1 部分:我为新手找到了这两个很棒的教程:
- 最basic一个
-
one 在东西出现时实际动画
第2部分:我只是在this answer找到解决方案
第 1 部分一步一步:
- 将
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; 行添加到/src/app/app.module.ts,然后:
@NgModule({
// Other arrays removed
imports: [
// Other imports
BrowserAnimationsModule
],
})
- 在要动画的component.ts中,添加:
import { trigger,state,style,transition,animate } from '@angular/animations';然后:
@Component({
// Here goes the selector and templates and etc.
animations: [
trigger('fadeInOut', [
state('void', style({
opacity: 0
})),
transition('void <=> *', animate(1000)),
]),
]
})
- 最后,在要制作动画的 HTML 项目中,添加
[@fadeInOut]。
如果一切都正确完成,您现在应该有一个动画(但它会在网页加载时发生,而不是在您滚动时发生。
第 2 部分分步说明:
- 创建一个 .ts 文件,例如
appear.ts 并复制粘贴此代码:
import {
ElementRef, Output, Directive, AfterViewInit, OnDestroy, EventEmitter
} from '@angular/core';
import { Observable, Subscription, fromEvent } from 'rxjs';
import { startWith } from 'rxjs/operators';
//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 = fromEvent(window, 'scroll').pipe(startWith(null))
.subscribe(() => {
this.saveScrollPos();
this.checkVisibility();
});
this.subscriptionResize = fromEvent(window, 'resize').pipe(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();
}
}
- 使用
import {AppearDirective} from './timeline/appear';将其导入并将其添加到导入中:
@NgModule({
declarations: [
// Other declarations
AppearDirective
],
// Imports and stuff
- 班上的某处做:
hasAppeared : boolean = false;
onAppear(){
this.hasAppeared = true;
console.log("I have appeared!"); // This is a good idea for debugging
}
- 最后,在 HTML 中添加以下两个:
(appear)="onAppear()" *ngIf="hasAppeared"
您可以通过检查控制台中的消息“我已经出现!”来检查它是否正常工作。