Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Angular: Animation doesnt start

I want to implement a text animation so following:
https://stackblitz.com/edit/text-animation-demo-with-animejs?file=src%2Fapp%2Fapp.component.html,src%2Fapp%2Fapp.component.ts

i copied to my file the code:

export class HeroSectionMainTextComponent {
  ngAfterViewInit(): void {
    // Wrap every letter in a span
    const textWrapper = document.querySelector('.an-1');
    textWrapper.innerHTML = textWrapper.textContent.replace(
      /\S/g,
      "<span class='letter'>$&</span>",
    );

    anime
      .timeline({ loop: true })
      .add({
        targets: '.an-1 .letter',
        scale: [4, 1],
        opacity: [0, 1],
        translateZ: 0,
        easing: 'easeOutExpo',
        duration: 950,
        delay: (el, i) => 70 * i,
      })
      .add({
        targets: '.an-1',
        opacity: 0,
        duration: 1000,
        easing: 'easeOutExpo',
        delay: 1000,
      });
  }
}

but i got an error:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

TS18047: 'textWrapper' is possibly 'null'.

so i tried adding ?. like this:

 const textWrapper = document.querySelector('.an-1');
    textWrapper?.innerHTML = textWrapper?.textContent.replace(
      /\S/g,
      "<span class='letter'>$&</span>",
    );

but it didnt work. How to make it work and why on stackblitz it works?

EDIT:

import { Component, AfterViewInit } from '@angular/core';
declare var anime: any; // declare like this
import 'zone.js';

@Component({
  selector: 'app-hero-section-main-text',
  standalone: true,
  imports: [],
  templateUrl: './hero-section-main-text.component.html',
  styleUrl: './hero-section-main-text.component.css',
})
export class HeroSectionMainTextComponent {
  ngAfterViewInit(): void {
    // Wrap every letter in a span
    const textWrapper = document.querySelector('.an-1');
    if (textWrapper) {
      textWrapper.innerHTML =
        textWrapper?.textContent?.replace(
          /\S/g,
          "<span class='letter'>$&</span>",
        ) || '';
    }

    anime
      .timeline({ loop: true })
      .add({
        targets: '.an-1 .letter',
        scale: [4, 1],
        opacity: [0, 1],
        translateZ: 0,
        easing: 'easeOutExpo',
        duration: 950,
        delay: (el: any, i: any) => 70 * i,
      })
      .add({
        targets: '.an-1',
        opacity: 0,
        duration: 1000,
        easing: 'easeOutExpo',
        delay: 1000,
      });
  }
}

now i dont get any error but the animation simply doesnt start..

>Solution :

We just need to check the left hand side textWrapper property is not null, we can use a if condition to check this! also added || '' so that the right hand side does not return undefined but empty string instead!

You have strictNullChecks enabled in typescript, could also be due to strict enabled in tsconfig.json

const textWrapper = document.querySelector('.an-1');
if (textWrapper) {
  textWrapper.innerHTML =
    textWrapper?.textContent?.replace(
      /\S/g,
      "<span class='letter'>$&</span>"
    ) || '';
}

full code

import { Component, AfterViewInit } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { AppModule } from './app.module';
declare var anime: any; // declare like this
import 'zone.js';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  imports: [AppModule],
  standalone: true,
})
export class AppComponent implements AfterViewInit {
  ngAfterViewInit(): void {
    // Wrap every letter in a span
    const textWrapper = document.querySelector('.an-1');
    if (textWrapper) {
      textWrapper.innerHTML =
        textWrapper?.textContent?.replace(
          /\S/g,
          "<span class='letter'>$&</span>"
        ) || '';
    }

    anime
      .timeline({ loop: true })
      .add({
        targets: '.an-1 .letter',
        scale: [4, 1],
        opacity: [0, 1],
        translateZ: 0,
        easing: 'easeOutExpo',
        duration: 950,
        delay: (el, i) => 70 * i,
      })
      .add({
        targets: '.an-1',
        opacity: 0,
        duration: 1000,
        easing: 'easeOutExpo',
        delay: 1000,
      });
  }
}

bootstrapApplication(AppComponent);

Stackblitz Demo

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading