Using the example from CDK drag and drop, I want to add a preview of the dragged element with left and top positions without the transform style.
<div class="example-boundary">
<div class="example-box" cdkDragBoundary=".example-boundary" cdkDrag>
I can only be dragged within the dotted container
</div>
</div>
<button> Preview the dragged element </buttona>
import {Component} from '@angular/core';
import {CdkDrag} from '@angular/cdk/drag-drop';
/**
* @title Drag&Drop boundary
*/
@Component({
selector: 'cdk-drag-drop-boundary-example',
templateUrl: 'cdk-drag-drop-boundary-example.html',
styleUrls: ['cdk-drag-drop-boundary-example.css'],
standalone: true,
imports: [CdkDrag],
})
export class CdkDragDropBoundaryExample {}
When you drag the element you have this div in DOM
<div _ngcontent-ng-c2320506461="" class="example-boundary">
<div _ngcontent-ng-c2320506461="" cdkdragboundary=".example-boundary" cdkdrag="" class="cdk-drag example-box" style="transform: translate3d(202px, -2px, 0px);">
I can only be dragged within the dotted container
</div>
</div>
When you drag the element and click the preview button it should open the preview element which looks like this.
<div class="example-boundary">
<div class="example-box" style="left: 96.13%; top: 9.92%; display: block;">
Now I can't be dragged, sorry
</div>
</div>
Meaning the transform style should be replaced with left and top positions.
@angular/cdk/drag-drop
internally uses transform property for placing the box. Whether top
, left
and position
properties are used or transform
is used in internal detail of the package and should be understood to be encapsulated. You can achieve the same results using both ways. If there is anything specific you want to do with top
and left
properties, you can either compute them from transform
and elements original position or code drag function in pure JS.
Following is a pure JS version of what you want to do.
const box = document.querySelector('.example-box');
const boundary = document.querySelector(box.getAttribute('cdkDragBoundary') || '');
const posDisplay = document.querySelector('#pos');
const offset = {
x: 0,
y: 0
};
const onMouseMove = (e) => {
e.preventDefault();
const [cx, cy] = [e.clientX, e.clientY];
const {
width,
height
} = box.getBoundingClientRect();
let top = cy - offset.y;
let left = cx - offset.x;
const {
width: bw,
height: bh
} = boundary?.getBoundingClientRect();
top = Math.min(top, (bh || innerHeight) - height);
top = Math.max(top, 0);
left = Math.min(left, (bw || innerWidth) - width);
left = Math.max(left, 0);
box.style.top = top + 'px';
box.style.left = left + 'px';
posDisplay.innerText = `left: ${left}px, top: ${top}px`;
};
box.onmousedown = e => {
e.preventDefault();
offset.x = e.clientX - box.offsetLeft;
offset.y = e.clientY - box.offsetTop;
window.onmousemove = onMouseMove;
window.onmouseup = () => {
window.onmousemove = null;
window.onmouseup = null;
};
}
.example-boundary {
position: relative;
border: 1px dotted gray;
width: 80vw;
height: 80vh;
margin: 0 10vmin;
}
.example-box {
position: absolute;
width: 200px;
padding: 10px;
border-radius: 10px;
border: 1px solid green;
cursor: grab;
}
#pos {
height: 50px;
padding: 0 10px;
}
<p id="pos">left: 0, top: 0</p>
<div class="example-boundary">
<div class="example-box" cdkDragBoundary=".example-boundary">
I can only be dragged within the dotted container
</div>
</div>