angulartypescripthammer

ngFor with Hammer JS swipe function in Angular 7 to slice a index


While using Hammer js swipe function with *ngFor in angular. The result expected was a swipe for particular index of tile and that tile will be removed. But by doing that the animation is not working now. The code which I have written is:

https://stackblitz.com/edit/angular-animations-lib-demo-ahykzr?file=src%2Fapp%2Fapp.component.html

.html:

<div style="margin: 10px">
    
    <div class="container" *ngFor="let data of datas; let i = index">
      
        <mat-card class="example-card animated flip infinite" [@enter1] style="margin: 20px 0px;" 

        [@cardAnimator]="animationState" 
        (@cardAnimator.done)="resetAnimationState()"
        (swipeleft)="startAnimation('slideOutLeft',i)"
        (swiperight)="startAnimation('slideOutRight',i)">
          
        <div>
            <h4>{{data}}</h4>
        </div>
        </mat-card>
        
    </div>
    
</div>

.scss:

.e-header {
    padding-bottom: 20px;
}

.pt-3, .py-3 {
    padding-top: 1rem!important;
}
.container {
    width: 100%;
    padding-right: 15px;
    padding-left: 15px;
    margin-right: auto;
    margin-left: auto;
}
.text-right {
    text-align: right!important;
}

.justify-content-end {
    -ms-flex-pack: end!important;
    justify-content: flex-end!important;
}
.h3, h3 {
    font-size: 27px;
    letter-spacing: 0px;
    line-height: 28px;
    font-family: Roboto, "Helvetica Neue", sans-serif;
}
.h6, h6 {
    font-size: 13px;
    line-height: 12px;
    letter-spacing: 0.15px;
    font-family: Roboto, "Helvetica Neue", sans-serif;
}
h5, h5 {
    font-size: 13px;
    letter-spacing: 0px;
    font-family: Roboto, "Helvetica Neue", sans-serif;
}
.h4, h4 {
    font-size: 18px;
    letter-spacing: 0.25px;
    font-family: Roboto, "Helvetica Neue", sans-serif;
}
.try{
    font-size: 35px;
    position: absolute;
    color: red;
    bottom: -1px;
    left: 12px;
}

.ts :

import { Component, OnInit } from '@angular/core';
import { trigger, 
    state, 
    style, 
    animate, 
    transition, 
    keyframes } from '@angular/animations';


import {
  bounceInLeftOnEnterAnimation,
  flipInXOnEnterAnimation,
} from 'angular-animations';
export const slideOutLeft = [
    style({transform: 'translate3d(0, 0, 0)', offset: 0}),
    style({transform: 'translate3d(-150%, 0, 0)', opacity: 0, offset: 1}),
]
export const slideOutRight = [
    style({transform: 'translate3d(0, 0, 0)', offset: 0}),
    style({transform: 'translate3d(150%, 0, 0)', opacity: 0, offset: 1}),
]
export const slideOutDown = [
    style({transform: 'translate3d(0, 0, 0)', offset: 0}),
    style({transform: 'translate3d(0, -150%, 0)', opacity: 0, offset: 1}),
]
export const slideOutUp = [
    style({transform: 'translate3d(0, 0, 0)', offset: 0}),
    style({transform: 'translate3d(0, 150%, 0)', opacity: 0, offset: 1}),
]
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
  animations: [
    trigger('cardAnimator', [
      transition('* => slideOutLeft', animate(1000, keyframes(slideOutLeft))),
      transition('* => slideOutRight', animate(1000, keyframes(slideOutRight))),
      transition('* => slideOutDown', animate(1000, keyframes(slideOutDown))),
      transition('* => slideOutUp', animate(1000, keyframes(slideOutUp))),
    ]),
    bounceInLeftOnEnterAnimation({ anchor: 'enter1' }),

  ]
})
export class AppComponent  {
  datas = [1,2,3,4,5,6,7];
  animationState: string;
  animationState1: string;
  ngOnInit() {
  }
  asd :any ;
  startAnimation(state,index) {
    console.log(state)
        console.log(index)

    this.asd = index;
    if (!this.animationState) {
      this.animationState = state;
    }
  }
  

  resetAnimationState() {
    this.animationState = '';
  }

}

app.module.ts:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { FormsModule } from '@angular/forms';
import {
  MatFormFieldModule,
  MatSelectModule,
  MatButtonModule,
  MatToolbarModule,
  MatInputModule,
  MatSidenavModule,
  MatIconModule,
  MatListModule
} from '@angular/material';
import { MatCardModule } from '@angular/material';

import { AppComponent } from './app.component';


@NgModule({
  declarations: [
    AppComponent,
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    FormsModule,
    MatFormFieldModule,
    MatSelectModule,
    MatButtonModule,
    MatToolbarModule,
    MatInputModule,
    MatSidenavModule,
    MatCardModule,
    MatIconModule,
    MatListModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule {}

Solution

  • After the changes from this SO change your resetAnimationState to pass the index and use splice only when animationState[index] was 'slideOutLeft' or 'slideOutRigth'

      resetAnimationState(index) {
        if (this.animationState[index]=='slideOutLeft' || this.animationState[index]=='slideOutRight')
          this.datas.splice(index,1)
          this.animationState.splice(index,1)
      }
    

    stackblitz