Marcel
Marcel

Reputation: 1142

Angular5: Animation to exchange content of a div, animate height change of a container and fade out of the content. ("almost good" Plunker included)

I am trying to implement an animation in Angular 5 to exchange the content of a container and animate the height to fit the new content. The stages of the animations would be (or just see in Plunker) 1. Fade the current content out (opacity 1->0) 2. Animate height of the container to fit the new content 3. Fade the new content in (opacity 1->0)

I have made some implementation, but there is a strange jumping of the height of the container div at the beginning and end of the animation.

What would be a better way to do this animation and prevent the jittering?

https://plnkr.co/edit/2TtKHfVkjDtITaAIM6bR?p=preview

Background - in my application I have a flyout/dropdown/popup/modal container which has its height based on the content it holds, and the content changes when a user is logged-in/logged-out.

Edit: seems like the border is the culprit, I still would like to know what is the best practice for this kind of animations in angular (keyframes vs another method).

code from plunker app.ts with Angular 5:

//our root app component
import {Component, NgModule, VERSION} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import {
  trigger,
  state,
  style,
  transition,
  animate,
  keyframes,
  group
} from '@angular/animations';


@Component({
  selector: 'my-app',
  template: `
    <div style="border: black solid 1px; padding: 10px">
    <div [@list1]="!displayRed" style="border:blue solid 1px; background: lightblue">
          content 1 <br/>
          content 1 <br/>
          content 1 <br/> 
          content 1 <br/>
          content 1 <br/>
          content 1 <br/>
          content 1 <br/>
    </div>
    <div [@list1]="displayRed" style="border: red solid 1px; background: pink">
          content 2 <br/>
          content 2 <br/>
          content 2 <br/> 
          content 2 <br/>
    </div>
    </div>
    <br/>
    <button (click)="switchContent()"> Switch Content </button>
  `,
  animations:[    trigger('list1', [
      state('true', style({
        opacity: 1,
      })),
      state('false', style({
        opacity: 0,
        height:0,
        display:'none'
      })),
      transition('false => true', [
        style({
          opacity: 0,
          height:0
        }),
        animate(2000, keyframes([
          style({ opacity: 0, height:0,  offset: 0 }),
          style({ opacity: 0, height:0,  offset: 0.4 }),
          style({ opacity: 0, height:'*', offset: 0.6 }),
          style({ opacity: 1, height:'*', offset: 1 }),
        ])
        )
      ]),
      transition('true => false', [
        animate(2000, keyframes([
          style({ opacity: 1, height:'*', offset: 0 }),
          style({ opacity: 0, height:'*', offset: 0.4 }),
          style({ opacity: 0, height:0,  offset: 0.6 }),
          style({ opacity: 0, height:0,  offset: 1 }),
        ])
        )
      ])
    ])
    ]
})
export class App {
  name:string;
  displayRed:boolean=false;

  switchContent(){
    console.log('switch');
    this.displayRed=!this.displayRed;
  }

  constructor() {
    this.name = `Angular! v${VERSION.full}`
  }
}

@NgModule({
  imports: [ BrowserModule, BrowserAnimationsModule ],
  declarations: [ App ],
  bootstrap: [ App ]
})
export class AppModule {}

Upvotes: 1

Views: 1428

Answers (1)

Marcel
Marcel

Reputation: 1142

Border, padding, margin have to be set to zero and also overflow:hidden has to be set to prevent jumping.

Upvotes: 0

Related Questions