1

I am trying to create a fade-in animation in my Angular App everytime the background changes, but cannot seem to find a way to do so.

This is the (related) code I have at the moment:

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;
          })
      }

What I did was basically looped through an array of images stored in the 'assets' folder, causing the background to change every approx. 8s, with an Observable.

The style animation (fade in effect) is applied only when I first enter the page, and not when the background is altered. I understand that there is no re-rendering of the page (hence the animation is not applied) when the background is changed the way I did it. However, I have been unable to come up with a solution.

Thank you for taking the time to read this, and I'm looking forward to hearing your solutions!

1 Answer 1

1

You should use Angular animations states to trigger the animation more easily. So each time the background changes, you toggle the states twice to fade out and fade in again.

Here is a StackBlitz example I created.

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>
Sign up to request clarification or add additional context in comments.

2 Comments

Working well. Thanks so much :-)
Your Stackblitz throws a ExpressionChangedAfterItHasBeenCheckedError, so it appears to work but how reliably i'm not sure. Keen to fix this because I'd like a solution as well.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.