0

I'm using "@angular/cdk": "^15.2.4" and having difficulties figuring out how to resolve the problem in the title. That is, I have some parent DOM element coming from an external library that gets a transform: translate3d(); applied, and I have some draggable elements inside that element using CDK's dragdrop feature. When start dragging, the drag helper element gets a position: fixed !important style, its top and left properties are set to 0, and its dragging position is applied via transform: translate3d() as well.

The problem is, due to the translate3d on the parent element, the draggable's position: fixed causes the containing block for the dragging element will be that particular parent, instead of the whole HTML element, which I think is the base of calculations for the translate3d() operation on the draggable element. It seems like CDK's drag does not consider if there's a parent element with a transform property set, which results in wrong numbers being calculated for transformation. Does anyone have an idea how could I overcome this?

I was trying to set transform:none and playing around with positions but no luck so far. I can think of a JS solution of recalculating the translate values manually, but I'd be curious if there's a simpler way to do this.

Sleeper9
  • 1,707
  • 1
  • 19
  • 26
  • As idea (really I don't know if work), you can try to get in mousedown the "transform" and store in a variable the "offset" position and the "dimensions". In onDragMove you add the offset position like this [SO](https://stackoverflow.com/questions/73766218/how-to-change-preview-of-the-dragged-image-size-only-dragging-in-angular-materia/73769520#73769520). – Eliseo Apr 13 '23 at 13:23
  • Yeah, I was thinking of using `cdkDragConstrainPosition` input of [CDKDrag directive](https://material.angular.io/cdk/drag-drop/api#CdkDrag) for something similar, but this feels overly complicated for such a simple-looking problem... – Sleeper9 Apr 13 '23 at 14:08

1 Answers1

0

OK, so I ended up transforming the transform style to top+left for the ancestor element.

In details, before dragging, I extracted the transformation matrix into an array of numbers by splitting up the transform string, and used the last 2 values to set top and left values. After dragging is finished, I write back the original transform style based on the previous top and left values.

Code to get offset values:

const getOffsetFromTransform = (element) => {
  const originalTransform = getComputedStyle(element).transform;
  const transformMatch = originalTransform.match(/^matrix3d\((.+)\)$/);

  // Extract the translation values from the transform matrix
  const matrixValues = transformMatch[1].split(',').map(parseFloat);
  const offsetX = matrixValues[12];
  const offsetY = matrixValues[13];

  return {offsetX, offsetY};
}
Sleeper9
  • 1,707
  • 1
  • 19
  • 26