feat(cdk/drag-drop): X and Y as percentage values instead of px
Feature Description
We are developing a mobile app in which users should be able to move elements back and forth in a certain area. The position of the elements should obviously be identical for every user. However, this does not work since each user has a different smartphone and therefore a different screen width, as cdk/drag-drop works with px values. One should be able to switch from px to % in order to ensure the correct position regardless of the screen resolution (or the width of the boundary element).
This may be tricky to do, because we currently map 1px of movement to 1px in the transform value.
This may be tricky to do, because we currently map 1px of movement to 1px in the
transformvalue.
My math skills are at the level of a 12-year-old. 😅 Otherwise, I would participate in solving this problem. But, as I understand it, one must also scale the object to be moved by x% proportionally to the boundary. This ensures that the movable objects appear visually the same size at each scale.
I just realized that using transform: translate3d(97%, 100%, 0px) in percentage terms does not behave as I expected...
Unfortunately, this is really a problem, thus drag is not usable if it represents an element that is synchronized across multiple users, each with different screen widths.
A friend mentioned this conversion as a possible solution... however, I don't understand much of it. Maybe it helps with this issue:
Canvas:
baseCanvasWidth: 1080px
baseCanvasHeight: 1920px
A random image on the canvas:
originalImageWidth: 32px
originalImageHeight: 32px
originalImagePosX: 100px
originalImagePosY: 100px
---
Case 1:
deviceCanvasWidth: 720px
deviceCanvasHeight: 1280px
-> Results for Case 1 (see below) <-
Case 1 random image on the canvas:
imageWidth: 720px / 1080px * 32px = 21.333px
imageHeight: 1280px / 1920px * 32px = 21.333px
imagePosX: 720px / 1080px * 100px = 66.666px
imagePosY: 1280px / 1920px * 100px = 66.666px
---
Formula:
deviceCanvasWidth / baseCanvasWidth * originalImageWidth = rescaledImageWidth
deviceCanvasHeight / baseCanvasHeight * originalImageHeight = rescaledImageHeight
deviceCanvasWidth / baseCanvasWidth * originalImagePosX = rescaledImagePosX
deviceCanvasHeight / baseCanvasHeight * originalImagePosY = rescaledImagePosY
I'm currently facing a similar problem where I have a container (that holds cdkDrag elements) which I scale using CSS transformation, if not mistaken the behaviour is similar to the one aforementioned here.
I think adding an Input like cdkDragScaling and incorporating it into the following could help. https://github.com/angular/components/blob/436301f41f0a44f60c99bda4d121f893a6b63d55/src/cdk/drag-drop/drag-ref.ts#L648
When using cdkDrag in an application, one could then for example set [cdkDragScaling]="{ x: .75, y: .5 }" and the scaling would be applied onto the elements movement. That would leave the work of calculating the scaling on the side of the dev using cdkDrag and would leave a lot of freedom, if I'm not entirely mistaken.
edit: sadly I don't have a lot of time on my hands to test it out
@Lubjan Do I understand you correctly? The necessary features already exist in cdkDrag for clean scaling?
@Lubjan Do I understand you correctly? The necessary features already exist in cdkDrag for clean scaling?
No, it is a proposal to add cdkDragScaling as a feature into cdkDrag itself. If something like that already exists, I am not aware of it or wasn't able to find it yet. (I don't mean visibly scaling the element)