angularangular-animations

Angular how to delay/stagger the animation inside of child components


I have a child component with animations

child.component.ts

@Component({
  selector: 'child',
  animations:[
    // animations
   ]
})
export class ChildComponent { ... }

And a parent component, which has 2 of the child components in the html

parent.component.hmtl.ts

...
<child></child>
<child></child>
...

Stackblitz Example

What I want to achieve is to stagger the animations of the child components in the parent component. Therefore second child component should start animation after X seconds.

animateChild() sounds like it might work but I cant figure out how I can use it. Is that the right solution? If so an example would be really helpful.

Thanks in advance

EDIT: animateChild() does not seem to work for this case. Appearantly it only works on animations that are defined in the parent component.

EDIT2: I think there might be a workaround by adding a delay to the animations inside of the child components.

child.component.ts

@Component({
  selector: 'child',
  animations:[
    animate(x),
    // animations
   ]
})
export class ChildComponent { ... }

The x would be a variable that would increase for every child component. This workaround looks kinda messy to me

EDIT3: the anwers so far are more or less the solution i mentioned in my second edit. While those do work I still consider those as workarounds.

I am looking for a solution that only involves the parent component therefore the child component should stay the way it is like in this non working example


Solution

  • As per angular documentation in animation function.

    The second argument, delay, has the same syntax as duration. For example:

    Wait for 100ms and then run for 200ms: '0.2s 100ms'

    Full reading here

    So, our goal is to pass the second parameter something like this

    animate('2000ms {{delay}}ms'
    

    first, lets add input parameter to your child component so we can accept the input values from the parent ones:

    export class ChildComponent implements OnInit {
      @Input() delay: number = 0;
      constructor() { }    
    }
    

    Now, lets pass down the parameter value form the parent component

    <p>child1</p>
    <app-child [delay]="0"></app-child>
    
    <p>child2</p>
    <app-child [delay]="1000"></app-child>
    <p>child2 should have a delay</p>
    

    In your child component we need to pass this parameter to the animation trigger so it would look like this

    <p [@childAnimation]="{value:'',params:{delay:delay}}">
        IIIIIIIIIIIIIIIIII
    </p>
    

    And finally we can change our animation to support this parameter value

    animations: [
        trigger('childAnimation', [
          transition(':enter', [
            animate('2000ms {{delay}}ms', style({ transform: 'translateX(80%)' })),
            animate('2000ms', style({ transform: 'translateX(0)' })),
          ], { params: { delay: 0 } })
        ])
      ]
    

    all good now, you should working delay to the inputs now.

    Check out demo here