Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reset transform offset in Angular Material Drag and Drop

I have a <div> element with position: absolute inside a container with position: relative. Its left and top properties are bound to data X and Y in the component.ts. My purpose is to move the div inside my container using cdk drag and drop.

On the dragEnded event I retrive the data I need to update the coordinates X and Y and so begins the problem...

<div
  class="character"
  [style.left.px]="x"
  [style.top.px]="y"
  cdkDrag
  cdkDragBoundary=".grid-container"
  (cdkDragEnded)="dragEnded($event, c)"
></div>

I notice that cdk drag and drop apply a property transform: translate3d(x,y,z) in order to move my div, starting from its original position. So, if I want my div left and top to be bound to my backend properties I can just calculate new coordinates on dragEnd event, apply them, and reset the transform property made by cdk. Everything works.

But the next time I drag the element, material don't apply the transform starting from the new absolute position of my div, but from the original one.

I thought one solution could be to check if the CdkDragEnd event contains the data relative to the transform starting point and reset it, but I didn't find anything.

Any idea if this proprty is hidden somewhere in the CdkDragEvent? Or have any other solution to this problem?

like image 772
Loreppo Avatar asked Apr 20 '26 20:04

Loreppo


2 Answers

In method that takes CdkDragEnd event you can reset transform property with event.source._dragRef.reset();. Example:

public dragEnded(event: CdkDragEnd): void {
    if (this.dragEnd.type === "cell" && this.dragStart.type !== "cell") {
      this.moveFromList1To2(event.source.element.nativeElement.id);
      event.source._dragRef.reset();
    }
  }
like image 157
bakunet Avatar answered Apr 22 '26 11:04

bakunet


Even if the version of @bakunet is working, this is considering bad practice to access private method and may not work, depend on your compiler.

Here on the official angular website, you can find the following solution.

Use of the ckdDragFreeDragPosition

<p>
  <button (click)="resetPosition()">reset position</button>
</p>

<div class="character" cdkDrag [cdkDragFreeDragPosition]="dragPosition">
  Drag me around
</div>
import {Component} from '@angular/core';

/**
 * @title Programmatically setting the free drag position
 */
@Component({
  selector: 'cdk-drag-drop-free-drag-position-example',
  templateUrl: 'cdk-drag-drop-free-drag-position-example.html',
  styleUrls: ['cdk-drag-drop-free-drag-position-example.css'],
})
export class CdkDragDropFreeDragPositionExample {
  dragPosition = {x: 0, y: 0};

  resetPosition() {
    this.dragPosition = {x: 0, y: 0};
  }
}

ckdDragFreeDragPosition use :

By default, standalone cdkDrag elements move from their normal DOM position only when manually moved by a user. The element's position can be explicitly set, however, via the cdkDragFreeDragPosition input. Applications commonly use this, for example, to restore a draggable's position after a user has navigated away and then returned.

like image 38
Raphaël Balet Avatar answered Apr 22 '26 12:04

Raphaël Balet