cssangulartypescriptsasscss-animations

Angular - Infinite animation of moving lines


I am trying to render an infinite animation of lines going from page bottom to top.

Here is the result :

https://stackblitz.com/edit/angular-xyke249e?file=src%2FAnimationPage%2Fanimation.component.ts

As you can see lines are moving as i would like, but with some looseness, or blur, sometimes even frames splitting in two lines, and the screen is hard to focus on.

Is there a way to make the same thing smoothly ?


Solution

  • The creating/destroying of elements inside the *ngFor might be the reason for this.

    For better tracking I added a trackBy to the for loop, so that the elements have a specific ID to track by.

    The main fix, is to use animation-delay to delay the animation.

    This will create a smoother animation without the creation/destruction of elements.

    <div
      *ngFor="let line of lines; trackBy: trackBy; let index = index"
      class="line"
      [style.animation-duration]="speed + 'ms'"
      [style.animation-delay]="500 * (index + 1) + 'ms'"
    ></div>
    

    Full Code:

    SCSS:

    .container {
      background-color: grey;
      color: rgb(39, 134, 216);
      overflow-y: hidden;
      width: 50vw;
    }
    
    .line {
      position: absolute;
      width: 100%;
      height: 1px;
      animation: moveUp linear infinite;
      border: 1px solid rgb(0, 0, 0);
      animation-delay: 5000;
      bottom: -20px;
    }
    
    @keyframes moveUp {
      from {
        bottom: -20px; /* Hors de l'écran en bas */
      }
      to {
        bottom: 100%; /* Hors de l'écran en haut */
      }
    }
    

    TS:

    import { Component } from '@angular/core';
    import { CommonModule } from '@angular/common';
    
    @Component({
      selector: 'app-animation',
      templateUrl: './animation.component.html',
      styleUrls: ['./animation.component.scss'],
      standalone: true,
      imports: [CommonModule],
    })
    export class AnimationComponent {
      speed: number = 3000;
      interval: number = 500;
    
      lines: any[] = [];
    
      ngOnInit() {
        this.startLinesAnimation();
      }
    
      trackBy(_: any, index: number) {
        return index;
      }
    
      startLinesAnimation(): void {
        this.lines.push({});
        this.lines.push({});
        this.lines.push({});
        this.lines.push({});
        this.lines.push({});
        this.lines.push({});
        this.lines.push({});
        this.lines.push({});
        this.lines.push({});
        this.lines.push({});
        // setInterval(() => {
        //   if (this.lines.length >= 10) {
        //     this.lines.shift(); // Supprime la barre la plus ancienne
        //   }
        //   this.lines.push({}); // Ajoute une nouvelle barre
        // }, this.interval);
      }
    }
    

    Stackblitz Demo