我想淡入显示在视口中的多个垂直堆叠的组件(每个组件都是一种编程语言, app-skill )。我的问题是,当第一个组件进入视口时,它会正确淡入,但也会淡入他下面的所有其余组件,并且我希望其余组件仅在它们出现在视口中时才具有动画效果。
skills.component.html
<section class="skills">
<div class="heading__grid">
<h1 class="heading__grid-title">My Skills</h1>
<div class="heading__grid-underline"></div>
</div>
<div class="skills__grid">
<app-skill
(appear)="onAppear()"
[@visibilityState]="visibility"
*ngFor="let skill of skills; index as i"
[skill]="skill"
[i]="i"
>
</app-skill>
</div>
</section>
skills.component.ts
import { Component, OnInit } from '@angular/core';
import { Skill } from './skill.model';
import { visibilityStateTrigger } from './animations';
@Component({
selector: 'app-skills',
templateUrl: './skills.component.html',
styleUrls: ['./skills.component.scss'],
animations: [visibilityStateTrigger]
})
export class SkillsComponent implements OnInit {
visibility: string = 'hide';
skills: Skill[] = [
new Skill('JavaScript', '65%'),
new Skill('HTML', '70%'),
new Skill('CSS', '70%'),
new Skill('React', '60%'),
new Skill('Angular 2+', '40%'),
new Skill('Git', '60%'),
new Skill('Java', '70%'),
new Skill('SQL', '80%'),
new Skill('SASS', '55%')
];
ngOnInit() {}
onAppear() {
console.log('onAppear fired');
this.visibility = 'show';
}
}
指令为(appear)
,它触发onAppear()
方法,该方法将变量可见性从 hide 更改为 show 。
appear-skill.directive.ts
import { Directive, ElementRef, HostListener, EventEmitter, Output } from '@angular/core';
@Directive({
selector: '[appear]'
})
export class AppearSkillDirective {
fired: boolean = false;
@Output() appear: EventEmitter<void> = new EventEmitter<any>();
constructor(public el: ElementRef) {}
@HostListener('window: scroll') inViewport() {
if ( !this.fired && this.isAnyPartOfElementInViewport(this.el) ) {
console.log('inside view port');
this.fired = true;
this.appear.emit();
}
}
isAnyPartOfElementInViewport(el: ElementRef ) {
const rect = el.nativeElement.getBoundingClientRect();
// DOMRect { x: 8, y: 8, width: 100, height: 100, top: 8, right: 108, bottom: 108, left: 8 }
const windowHeight = (window.innerHeight || document.documentElement.clientHeight);
const windowWidth = (window.innerWidth || document.documentElement.clientWidth);
// http://stackoverflow.com/questions/325933/determine-whether-two-date-ranges-overlap
const vertInView = (rect.top <= windowHeight) && ((rect.top + rect.height) >= 0);
const horInView = (rect.left <= windowWidth) && ((rect.left + rect.width) >= 0);
return (vertInView && horInView);
}
}
这是animation.ts
文件
import { trigger, state, style, animate, transition } from
'@angular/animations';
export const visibilityStateTrigger = trigger('visibilityState', [
state('shown', style({
opacity: 1
})),
state('hide', style({
opacity: 0
})),
transition('show => hide', animate('2s') ),
transition('hide => show', animate('2s') )
])
正如您在skills.components.ts
中的onAppear()
中所看到的,我仅将变量visibility
的值从 hide 更改为 show 。这会在所有组件(技能)中运行相应的动画[@visibilityState]
,而不仅仅是我想要的视口中的唯一动画。
任何帮助将不胜感激