Draggable div not being dragged using Hammerjs and Angular

316 views Asked by At

In my angular app I have cards and spaces, me cards(divs) can dragged and relocated fine on desktop, and I'm trying to use hammerjs to get it to work on mobile.

enter image description here

So I have added a (pan) event handler, which is being fired fine.

<div class="cardSpace" [ngClass]="debugStyle ? 'redBorder':''" [attr.id]="cardSpace.id" (click)="toggleCard()"
    [draggable]="!cardSpace.isEmpty" (dragstart)="drag($event)" (dragover)="allowDrop($event)" (drop)="drop($event)"
    (pan)="onPan($event)" [style.left.px]="left" [style.top.px]="top">
    <ng-container *ngIf="!cardSpace.isEmpty;">
        <img class="cardSize" [src]="getImagePath()">
    </ng-container>
</div>

here is the logic for the event handler

//mobile drag
onPan(event: any) {
    const elem = event.target;
    const el = new ElementRef(document.getElementById(this.cardSpace.id));

    if (!this.isDragging) {
      this.isDragging = true;

      this.lastPosX = 40;
      this.lastPosY = 80;
      /* did not work either
      if (el.nativeElement) {
        this.lastPosX = el.nativeElement.style.left;
        this.lastPosX = el.nativeElement.style.top;
      }
      */
      /* did not work 
      this.lastPosX = elem.offsetLeft;
      this.lastPosY = elem.offsetTop;
      */
    }

    // move our element to that position
    this.left = event.deltaX + this.lastPosX;
    this.top = event.deltaY + this.lastPosY;

    if (event.isFinal) {
      this.isDragging = false;
    }

    this.debugStyle = this.isDragging;
}

When I test the drag on mobile the card border is turning red when the drag starts (as expected) but the card(div) is not being moved even though I'm updating the left/top values used to locate the element.

The cards are layout initially in a row (flex container) - https://gallant-agnesi-5c5b96.netlify.app/ or a Matrix (one row above the other)

<div class="cardRow">

    <div *ngFor="let cs of cardSpaces; let i = index">
        <ng-container *ngIf="hasHeaders">
            <div class="header">
                {{ headers[i] }}
            </div>
        </ng-container>
        <app-card-space-component [cardSpace]="cs" (dragStarted)="dragStarted($event)"
            (dragFinished)="dragFinished($event)"></app-card-space-component>
    </div>
</div>

Do I need to "float" my div so that is not constrained by the cardRow ? what I'm doing wrong here ?

References:

Also I'm looking for a way to debug in mobile, since console.log errors are not very useful there.

1

There are 1 answers

0
Mauricio Gracia Gutierrez On

The reason the div was not being dragged is because the display was not set to absolute, to allow to be moved outside of its container.

So adding this style to the div, made it float

.redBorder {
    border: 1px red solid; //only for debug purposes
    position: absolute; //<---- this was the solution
}

When the drag starts I set the flag to make it draggable (position: absolute) and when the drag ends I remove that style

onPan(event: any) {
    const elem = event.target;

    if (!this.isDragging) {
      this.isDragging = true;

      this.lastPosX = elem.offsetLeft;
      this.lastPosY = elem.offsetTop;
    }

    // move our element to that position
    this.left = event.deltaX + this.lastPosX;
    this.top = event.deltaY + this.lastPosY;

    if (event.isFinal) {
      this.isDragging = false;
    }

    this.debugStyle = this.isDragging;
}