Как работать с viewPort в Angular и сделать подгрузку картинки при скролле к ней?

В Angular можно работать с viewport при помощи директивы IntersectionObserver, которая позволяет отслеживать, когда элемент становится видимым внутри viewport.

Для начала создадим директиву, которая будет отслеживать элементы, когда они появляются в viewport:

import { Directive, ElementRef, Output, EventEmitter, OnInit, OnDestroy } from '@angular/core';

@Directive({
  selector: '[appViewport]'
})
export class ViewportDirective implements OnInit, OnDestroy {
  private observer: IntersectionObserver;

  @Output() public onViewportEnter = new EventEmitter();

  constructor(private elementRef: ElementRef) {}

  ngOnInit() {
    const options = {
      root: null, // используем viewport в качестве root элемента
      rootMargin: '0px',
      threshold: 0.1 // задаем пороговое значение, при котором элемент считается видимым
    };

    this.observer = new IntersectionObserver(entries => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          this.onViewportEnter.emit();
          
          // отключаем наблюдение, чтобы избежать ненужных срабатываний
          this.observer.unobserve(this.elementRef.nativeElement);
        }
      });
    }, options);

    this.observer.observe(this.elementRef.nativeElement);
  }

  ngOnDestroy() {
    this.observer.disconnect();
  }
}

Теперь, чтобы загружать картинку при прокрутке к ней, нам нужно использовать эту директиву на элементе, который должен быть отслеживаем:

<div appViewport (onViewportEnter)="loadImage()">
  <!-- Картинка, которую нужно загрузить -->
  <img src="placeholder.jpg" [src]="imageSrc" alt="Image">
</div>

В компоненте, который содержит картинку, добавим логику загрузки картинки:

import { Component } from '@angular/core';

@Component({
  selector: 'app-image',
  templateUrl: './image.component.html',
  styleUrls: ['./image.component.css']
})
export class ImageComponent {
  public imageSrc: string;

  public loadImage() {
    // Загружаем картинку
    this.imageSrc = 'image.jpg';
  }
}

Теперь, когда элемент с директивой appViewport появится внутри viewport, сработает событие onViewportEnter, которое вызовет метод loadImage() в компоненте ImageComponent, и картинка загрузится.