How to register touch move over events in Angular?

Andrew Allen picture Andrew Allen · May 22, 2019 · Viewed 7.8k times · Source

Summarize the problem

Stackblitz - https://stackblitz.com/edit/angular-touch-playground

I'm trying register touch events and want to be able to touch my finger, drag and lift my finger resulting in every td of a table touched to be highlighted. This seems to be recorded as a pan event

I've used a dictionary pressed when any of the events click, touch, etc registers and [class.bg-warning]="pressed[i]" to highlight these.

Is there a way to register each td touched?

I've tried events like click, touchstart and hammerjs events (in app.module.ts I've imported via import 'hammerjs';) but I have to click every td to highlight it.

<td *ngFor="let dummy of ' '.repeat(48).split(''), let i = index"
    (press)="logPress(i)"
    (mouseenter)="logMouseIn(i)"
    (touchmove)="logTouchmove(i)"
    (click)="logClick(i)"
    (touch)="logTouch(i)"
    (touchend)="logTouchend(i)"
    (hover)="logHover(i)"
    (touchstart)="logTouchstart(i)"
    (touchend)="logTouchend(i)"
    (touchcancel)="logTouchcancel(i)"
    [class.bg-warning]="pressed[i]" >
</td>

example of setting pressed dictionary:

logClick(i: number) {
 this.event += '\n Click: '+ i.toString();
 this.pressed[i]=1;
}

Answer

Andrew Allen picture Andrew Allen · May 23, 2019

Stackblitz - https://stackblitz.com/edit/angular-touch-playground-pan-events

Change required - The key here is that if I were to do

(pan)="logPan(i)"

within the td then no matter the pan event would log the same i as the where the pan started.

Whereas if I do this

(pan)="logPan($event)"

I can access the $event coordinates (x, y) via evt.center.x / evt.center.y.

Utilizing coordinates - To convert the coordinates (x, y) to the td I care about I've used the elementFromPoint method which returns the topmost Element at the specified coordinates (relative to the viewport) and I've added an accessible attribute id to each td so that I can set my pressed dictionary, which is logging the td touched.

logPan(evt: any) {
  this.event += '\n Touch Pan: '+ `(${evt.center.x}, ${evt.center.y}, ${document.elementFromPoint(evt.center.x, evt.center.y).id})`
  this.pressed[document.elementFromPoint(evt.center.x, evt.center.y).id]=1;
}

Additional - pan doesn't seem to pick up where the finger first starts so an addtional (touchstart)="logTouchstart(i)" is required.

Credit - I figured this out after looking at the Stackblitz on the following blog: https://medium.com/angular-in-depth/gestures-in-an-angular-application-dde71804c0d0