1
votes

I'd like a smooth slide in and slide out animation using Angular animations. I am using ngSwitch to show/hide these components. The incoming component pushes the previous one up before it disappears out of view. I've tried adding a delay but this does not resolve the issue.

app.component.html

<div class="container" [ngSwitch]="counter">
  <div @slideInOut *ngSwitchCase="1"></div>
  <div @slideInOut *ngSwitchCase="2"></div>
  <div @slideInOut *ngSwitchCase="3"></div>
  <div @slideInOut *ngSwitchCase="4"></div>
</div>

<button (click)="handleNext()">Next</button>

app.component.scss

.container {
  div {
    width: 100px;
    height: 100px;
    background: pink;
  }
}

app.component.ts

import { Component } from '@angular/core';
import { slideInOut } from './shared/animations';


@Component({
  selector: 'my-app',
  styleUrls: ['./app.component.scss'],
  animations: [ slideInOut ],
  templateUrl: './app.component.html',
})
export class AppComponent {
  readonly name: string = 'Angular';
  counter = 1;

  boxArr = [1, 2, 3, 4]

  handleNext(){
    if(this.counter <= this.boxArr.length){
      this.counter += 1
    } else {
      this.counter = 1
    }
  }
}

animations.ts

import { trigger, state, style, transition, animate, keyframes } from "@angular/animations";


export const slideInOut =  trigger('slideInOut', [
    transition(':enter', [
      style({transform: 'translateX(100%)'}),
      animate('200ms ease-in', style({transform: 'translateX(0%)'}))
    ]),
    transition(':leave', [
      animate('200ms ease-in', style({transform: 'translateX(-100%)'}))
    ])
])

demo: https://stackblitz.com/edit/angular-na1ath

1
Are you sure you've posted the right link?Sergey
Nope, that was wrong. Edited.FakeEmpire

1 Answers

2
votes

The problem is that:

1) When you are dealing with display: block the element takes full line width no matter if there is some space left and therefore your slides were in two rows

2) If we solve this by adding display: inline-block we have to deal with that when there are two elements they take more space than one element. Meanwhile, translate doesn't actually move your element but only it's visible part (the "physical" shape is in the same position)

And thus it was solved by absolute positioning of your slides

https://stackblitz.com/edit/angular-zciezz?file=src/app/app.component.scss

.container {
  position: relative;
  width: 100px;
  height: 100px;

  div {
    position: absolute;
    top: 0;
    left: 0;
    width: 100px;
    height: 100px;
    background: pink;
  }
}