在 DOM element/style 发生变化时激活 Angular 动画

Activate Angular Animation upon change in DOM element/style

我试图在我的 Angular 应用程序中每次背景变化时创建一个淡入动画,但似乎找不到这样做的方法。

这是我目前拥有的(相关)代码:

HTML:

<div @fadeIn [style.backgroundImage]="currentImage" id="home" class="pt-5">
    <div class="container">
    ...
    </div>
</div>

CSS:

#home {
  background-image: url("/assets/img/friendship.jpeg");
  ...
}

TS:

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css'],
  animations: [
    trigger('fadeIn', [
      transition(':enter, :leave', [
        style({ opacity: 0 }),
        animate('2.5s ease-out')
      ])
    ])
  ]
})
export class HomeComponent implements OnInit {

    private bgImgs: Array<any>;
      private current: number = 0;
      currentImage;

      constructor(private sanitize: DomSanitizer) { 

        this.bgImgs = [
          ...
        ];
        this.currentImage = this.bgImgs[0]
      }


      ngOnInit() {
        Observable.interval(8669)
          .subscribe(x => {
            this.currentImage = this.sanitize.bypassSecurityTrustStyle(`url(${this.bgImgs[this.current]})`);
            this.current == this.bgImgs.length - 1 ? (this.current = 0) : ++this.current;
          })
      }

我所做的基本上是循环遍历存储在 'assets' 文件夹中的一系列图像,导致背景每隔大约改变一次。 8s,带有一个 Observable。

样式动画(淡入淡出效果)仅在我第一次进入页面时应用,而不是在背景更改时应用。我知道当背景按照我的方式更改时,不会重新呈现页面(因此不会应用动画)。但是一直想不出解决办法

感谢您花时间阅读本文,期待听到您的解决方案!

您应该使用Angular 动画状态来更轻松地触发动画。因此,每次背景发生变化时,您都会切换状态两次以淡出并再次淡入。

这是我创建的 StackBlitz example

app.component.ts

@Component({
  ...
  animations: [
    trigger('fadeIn', [
      state('in', style({ 'opacity': '1' })),
      state('out', style({ 'opacity': '0' })),
      transition('* => *', [
        animate(2000)
      ])
    ])
  ]
})

export class AppComponent implements OnInit {
  private bgImgs: Array<any>;
  private current: number = 0;
  currentImage;
  state = 'in';
  counter = 0;
  enableAnimation = false;

  constructor(private sanitize: DomSanitizer) {
    this.bgImgs = [...];
    this.currentImage = this.bgImgs[0]
  }


  ngOnInit() {
    Observable.interval(8669)
      .subscribe(x => {
        this.runAnimation();
      })
  }

  runAnimation() {
    this.enableAnimation = true;
    this.counter = 0;
    this.toggleState();
  }

  toggleImg() {
    this.currentImage = this.sanitize.bypassSecurityTrustStyle(`url(${this.bgImgs[this.current]})`);
    this.current == this.bgImgs.length - 1 ? (this.current = 0) : ++this.current;
  }

  onDone($event) {
    if (this.enableAnimation) {
      if (this.counter === 1) {
        this.toggleImg();
      }
      this.toggleState();
    }
  }

  toggleState() {
    if (this.counter < 2) {
      this.state = this.state === 'in' ? 'out' : 'in';
      this.counter++;
    }
  }
}

app.component.html

<div [@fadeIn]="state" (@fadeIn.done)="onDone($event)" [style.backgroundImage]="currentImage" id="home" class="pt-5">
    <div class="container"></div>
</div>