Angular12如何实现仅当元素进入视口时触发动画
Angular 12 滚动触发元素动画实现方案
以下是3种可落地的实现方案,优先推荐第一种,性能和复用性最优:
方案1:@angular/animations + Intersection Observer API(推荐)
无需额外引入第三方依赖,利用原生API实现高性能监听,不会造成滚动卡顿。
步骤1:导入动画模块
在app.module.ts中导入浏览器动画模块:
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; @NgModule({ imports: [ // 其他导入 BrowserAnimationsModule ] }) export class AppModule { }
步骤2:自定义滚动动画触发指令
封装通用指令复用逻辑,创建scroll-animation.directive.ts:
import { Directive, ElementRef, Input, OnInit } from '@angular/core'; import { AnimationBuilder, AnimationPlayer, style, animate } from '@angular/animations'; @Directive({ selector: '[appScrollAnimation]' }) export class ScrollAnimationDirective implements OnInit { // 可自定义传入动画配置 @Input() animationConfig = [ style({ opacity: 0, transform: 'translateY(30px)' }), animate('600ms ease-out', style({ opacity: 1, transform: 'translateY(0)' })) ]; private observer: IntersectionObserver; private player: AnimationPlayer; constructor(private el: ElementRef, private animationBuilder: AnimationBuilder) { } ngOnInit(): void { // 初始化元素初始状态 this.el.nativeElement.style.opacity = 0; // 初始化Intersection Observer this.observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { // 元素进入视口时触发动画 const factory = this.animationBuilder.build(this.animationConfig); this.player = factory.create(this.el.nativeElement); this.player.play(); // 只触发一次就取消监听,需要重复触发可删除下一行 this.observer.unobserve(this.el.nativeElement); } }); }, { threshold: 0.1 }); // 元素10%进入视口就触发,可自行调整 this.observer.observe(this.el.nativeElement); } ngOnDestroy(): void { this.observer?.disconnect(); this.player?.destroy(); } }
步骤3:模板中使用
给需要触发动画的元素加上指令即可:
<!-- 默认淡入上移动画 --> <div appScrollAnimation> 滚动到我这里就会触发动画 </div> <!-- 自定义动画效果 --> <div [appScrollAnimation]="[ style({ opacity: 0, transform: 'scale(0.8)' }), animate('400ms ease-out', style({ opacity: 1, transform: 'scale(1)' })) ]"> 自定义缩放淡入动画 </div>
方案2:第三方滚动动画库
如果不想自己封装逻辑,可以选择兼容Angular 12版本的开源滚动动画库,安装后按照文档给对应元素添加属性即可快速实现,支持的动画效果更丰富。
方案3:原生scroll事件监听(不推荐)
通过监听window的scroll事件,配合getBoundingClientRect()判断元素是否在视口内,需要额外加节流逻辑限制触发频率避免性能问题,仅适合非常简单的单页面场景。
注意事项
- Intersection Observer API已经支持所有现代浏览器,如果需要兼容极低版本浏览器,可以引入对应的polyfill。
- 动画触发阈值可以根据实际需求调整
threshold参数,取值范围0-1,0代表元素刚进入视口就触发,1代表元素完全进入视口才触发。 - 如果需要元素每次滚动进入视口都重复触发动画,删除指令中
unobserve的逻辑即可。
内容的提问来源于stack exchange,提问作者Moshiko
相关产品推荐
相关产品推荐

