3

I just started with Angular animations. And wan't to animate a *ngIf with it. Sadly it does't work :(. I don't get an error message. I tried several solutions from here, nothing worked. Also removing one of the animations doesn't change anything or removing one of the *ngIf-blocks entirely doesn't change anything. It just doesn't work, and there is also no error in the terminal or in the devtools visible.

Here the animations definition from the typescript.

animations: [
  trigger('inOutPaneAnimation', [
    state('true', style({ opacity: 1, transform: 'translateX(0)' })),
  state('void', style({ opacity: 0, transform: 'translateX(-100%)' })),
  transition(':enter', [animate('750ms ease-in-out')]),
  transition(':leave', [animate('600ms ease-in-out')]),
]),
trigger('inOutActiveItemAnimation', [
    state('true', style({ opacity: 1, transform: 'translateX(0)' })),
  state('void', style({ opacity: 0, transform: 'translateX(100%)' })),
  transition(':enter', [animate('600ms ease-in-out')]),
  transition(':leave', [animate('750ms ease-in-out')]),
]),

The HTML looks like this:

<div
  *ngIf="activeItem"
  [@inOutActiveItemAnimation]
  class="bt3-locations__active-item"
>
  <app-location-active-item
    [isSingleLocation]="isSingleLocation"
    [location]="activeItem"
    [showRouteLabel]="showRouteLabel"
  ></app-location-active-item>
</div>
<div *ngIf="!activeItem" [@inOutPaneAnimation] #paneContent>
  <div
    *ngTemplateOutlet="
      locations.data.length > 1 ? multipleGroups : group;
      context: { data: getGroups(), group: 0 }
    "
  ></div>
</div>

The BrowserAnimationsModule is imported, into the the parent module.

import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, Injector, NgModule } from '@angular/core';
import { createCustomElement } from '@angular/elements';
import { LocationItemComponent } from './location-item/location-item.component'; 
import { LocationsComponent } from './locations/locations.component';
import { LocationActiveItemComponent } from './location-active-item/location-active- 
item.component';
import { AccordionModule } from '../accordion/accordion.module';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

@NgModule({
    declarations: [
      LocationsComponent,
    LocationItemComponent,
    LocationActiveItemComponent,
  ],
  imports: [CommonModule, AccordionModule, BrowserAnimationsModule],
  exports: [],
  providers: [],
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
Pierre Spring
  • 10,525
  • 13
  • 49
  • 44
Marcel Bührig
  • 105
  • 2
  • 11

2 Answers2

5

This is how you create :enter and :leave animation

trigger("inOutPaneAnimation", [
    transition(":enter", [
        style({ opacity: 0, transform: "translateX(-100%)" }), //apply default styles before animation starts
        animate(
            "750ms ease-in-out",
            style({ opacity: 1, transform: "translateX(0)" })
        )
    ]),
    transition(":leave", [
        style({ opacity: 1, transform: "translateX(0)" }), //apply default styles before animation starts
        animate(
            "600ms ease-in-out",
            style({ opacity: 0, transform: "translateX(-100%)" })
        )
    ])
])

You don't even need property binding [], this is enough @inOutPaneAnimation

<div *ngIf="!activeItem" @inOutPaneAnimation #paneContent>
...
</div>

Read More Here

Here is a working stackblitz example

Note: Make sure to import BrowserAnimationsModule in main module.

Sameer
  • 4,758
  • 3
  • 20
  • 41
  • Sadly, doesn't work yet. That was the original way I followed, then I did fiddle with it a bit. But also with your code it doesn't work. May it be a problem that the animations don't work when *ngIf is not bound to a boolean? The class ng-trigger-inOutPaneAnimation is added, so I assume this is working. – Marcel Bührig May 03 '21 at 06:52
  • 1
    @MarcelBührig Answer updated, Added working example – Sameer May 03 '21 at 07:46
  • The BrowserAnimationsModule is imported in the main module. And we have other working code, which has animations. Just not :enter and :leave animations. – Marcel Bührig May 03 '21 at 08:50
  • Your solution worked. What you didn't know, and couldn't know, that the top element was on ViewEncapsulation.ShadowDom, then it is not working. – Marcel Bührig May 03 '21 at 09:18
  • Interestingly, the opacity on this stackblitz doesn't seem to be working? I think it might need `opacity: '1'` instead? – Adam Marshall Aug 24 '22 at 14:10
2

The solution, was fairly simple.

Make sure the ViewEncapsulation of your component is not set to ShadowDom. Then it is not working.

And also make sure to check @Sameer's answer. It is the right way to implement it.

Marcel Bührig
  • 105
  • 2
  • 11
  • That's good you fixed it yourself, I didn't know about that and there is no fix until now for this. Here is the [issue](https://github.com/angular/angular/issues/25672) – Sameer May 03 '21 at 09:36