Search code examples
angularionic-frameworkhammer.js

Dragging HTML element , implemented with HammerJS , is jittery on touch device


I have a list of HTML elements as cards stacked on top of each other. I am trying to drag the element with pan event using HammerJS

export class HomePage {
  @ViewChildren('slides') slides;
  @ViewChild('stack') stack;
  constructor(    
    this.cards = [1,2,3,4,5]
  }
  ngAfterViewInit(){
    let hammer = new Hammer.Manager(this.stack.nativeElement, {  preventDefault: true,
      recognizers: [      [ Hammer.Pan, { threshold: 2 }] ]
    });
    hammer.get('pan').set({ direction: window['Hammer'].DIRECTION_ALL });
    this.element = this.slides.first.nativeElement;
    hammer.on('panmove', (ev) => {
      this.handlePan(ev);
    });
  }
  handlePan(
    let deltaX = ev.deltaX;
    let deltaY = ev.deltaY;
    this.renderer.setStyle(this.element, 'transform',`translate(${deltaX}px,${deltaY}px)`);
  }
}

home.html

<ion-content  >
  <div #stack class="stack">
  <ion-card *ngFor = "let c of cards" #slides >
    <ion-card-content>
      c
    </ion-card-content>
  </ion-card>
  </div>
</ion-content>

home.scss

  ion-card{
    position: absolute;
    height: 400px;
  }

This works smoothly in browser but on touch devices its jittery. But if I remove position: absolute from css it works smoothly on touch devices as well but the cards are not stacked on top of each other. I just feel thepanmove event is triggered little late on touch devices for some reason.I am stuck on this problem for some days, any kind of help in figuring out the problem would be appreciated.


Solution

  • Finally found the answer. The issue is that styling is pretty slow on mobile devices. So have to make GPU acceleration in mobile devices. Simply add translate3d(0,0,0) which will pull in GPU acceleration.

    this.renderer.setStyle(elem,"transform",`translate3d(0, 0, 0) translate(${xtranslate}px,${ytranslate}px)`)