fix(drag): always put element under the mouse when dragging an element#2263
fix(drag): always put element under the mouse when dragging an element#2263adumesny merged 9 commits intogridstack:masterfrom
Conversation
|
@adumesny could you take a look 🙏 |
75fe294 to
2dd7bf0
Compare
|
thanks, will take a look. the title sounds scary, if all you wanted to fix was scrolling and scaling divs. |
adumesny
left a comment
There was a problem hiding this comment.
so looks like you are handling parent div scale (what about general transform including translate ?) for dragging only, what about for sizing do we need the same ?
|
I'm still working on it, I'll let you know as soon as I fixed all the issues |
|
@VincentMolinie @adumesny please can u fix this issue ASAP 😊 |
|
Everything should be fixed now :) |
Yes don't worry that was my top priority 😄 |
Yes don't worry that was my top priority 😄 |
|
@VincentMolinie appreciated TYT "D |
|
Well I don't need to take my time, as I say I did fix every issues I could find 👼 |
|
@adumesny it's back to you 😄 |
|
I pulled your changes locally, and demo/offset.html no longer works... can't trade scaling for offset. Also I even tried just scale and it's badly broken too ! so not sure what you tested this on... <div style="transform: scale(0.5, 0.5)">
<div class="grid-stack"></div>
</div>at this point I'm not sure what you are trying to fix (the code change looks much more complicated than I would expect) and didn't plan on fixing scale transform - I don't understand the use case for it. Browser scaling (for accessibility and others) works just fine, so why woudl you scale a div like above ??? |
|
Good catch @adumesny , sorry about that. I fixed those issue and I added a demo for the scale so we can test it easily |
|
if some people would like to use this fix I published a temporary version here until it's officially released 😄 : |
| if (style.position === 'relative' || style.position === 'absolute' || style.position === 'fixed') { | ||
| return el; | ||
| } else { | ||
| return this.getPositionContainerElement(el.parentElement); |
There was a problem hiding this comment.
there is no 'this' in static methods. use return Utils.getPositionContainerElement(...)
also no need to have else {} (a bit more compact, although less readable)
There was a problem hiding this comment.
check for el.parentElement being undefined
There was a problem hiding this comment.
For the check for el.parentElement being undefined, it's already checked by the first line, we do a !this.el so it's actually !el.parentElement
There was a problem hiding this comment.
you still have this.xyz in a static method!
|
your code is still completely breaking the main example demo/two.html (that and nested.html are the main 2 I always test against) at a minimum. when you say you have fixed all issue, I'm not sure what you are using. |
|
I would strongly suggest you use the existing code but add scaling to the mix, rather than a complete re-write which has proven to be unreliable so far... twice, it broke very basic flows... |
830b8d3 to
c73ac4b
Compare
|
I retested all the demo. now it should be good sorry about that 😥 |
|
@adumesny I work on a project where I drag items from a toolbar and drop them onto a grid. I even tried using the scale() function on the parent div to include a zoom effect on the area of my grid. Considering that several grids in the project need to have real scale, where a grid could occupy almost the entire screen or be a 200x200px grid with very small items, a zoom tool would be almost essential in my project. I'm mentioning this to clarify why I'm also trying to use the scale zoom. Unfortunately, browser support for this type of situation is only available for the entire page, not specifically for a div. |
|
I also need scale,Have you some methods to resolve?@adumesny |
|
I'll take a look this weekend... |
c73ac4b to
d6c9439
Compare
|
ran out of time over the weekend (had bugs to fix) and I will be on PTO soon, so this will have to wait till I get back the weekend in ~2 weeks |
|
I found some issues, so you can delay your review 😞 |
|
Okey I finally found the issue, and the reason why I had such a difference between the demo and my own project. So everything should be good now 🤞 |
61c0605 to
09d376c
Compare
| } | ||
| if (node) { | ||
| const rect = this.el.getBoundingClientRect(); | ||
| this._originalMousePositionInsideElement = { x: s.clientX - rect.left, y: s.clientY - rect.top }; |
There was a problem hiding this comment.
'_' is reserved for private vars, not protected. also rename to 'origRelativeMouse' and create based on this.mouseDownEvent otherwise you are off by 3+ pixels. ALSO don't really need that since we have this.mouseDownEvent (less vars to track)
There was a problem hiding this comment.
I'm using s which is the downEvent.el can move so no, we need to keep that variable
| position: { | ||
| left: rect.left - containmentRect.left, | ||
| top: rect.top - containmentRect.top | ||
| left: rect.left / scaleX, |
There was a problem hiding this comment.
so this has a very different meaning - was relative position, and now it's not (and scaled). Thsi will affect user of those values...
There was a problem hiding this comment.
It was private API. Everyone knows that using private API might break even when just patching a version 🤔. I can't really see the issue here 😅
There was a problem hiding this comment.
it's acutally protected (though it does have the _ which is usually reserved for private) so any subclass would break. but I have it @internal so no exported types for TS subclassing. need to clean and make private again.
but DDUIData is NOT private last time I checked and you changed the meaning...
There was a problem hiding this comment.
I didn't changed the meaning. This is the real position of the element. temporalRect has been updated to be at the right position
| if (style.position === 'relative' || style.position === 'absolute' || style.position === 'fixed') { | ||
| return el; | ||
| } else { | ||
| return this.getPositionContainerElement(el.parentElement); |
There was a problem hiding this comment.
you still have this.xyz in a static method!
|
still doens't behave the right way. two.html the item jumps to cursor (0,0) when starting a new (helper) drag say from the middle instead of being under the mouse also whe scaling (with zoom IN is much more optvious) you can see some weird wiggle animation where you must be changing the top & left position even though only scale bottom right happens. Didn't look at your code but it's not right. 20230806_154047.mp4 |
|
Everything is fixed @adumesny, thanks again for your review and sorry for the delay, I was in holidays ^^ |
| position: { | ||
| left: rect.left - containmentRect.left, | ||
| top: rect.top - containmentRect.top | ||
| left: rect.left / scaleX, |
There was a problem hiding this comment.
it's acutally protected (though it does have the _ which is usually reserved for private) so any subclass would break. but I have it @internal so no exported types for TS subclassing. need to clean and make private again.
but DDUIData is NOT private last time I checked and you changed the meaning...
| let el = element; | ||
|
|
||
| // Check if element is visible, otherwise the width/height will be of 0 | ||
| while (el && !el.offsetParent) { |
There was a problem hiding this comment.
"element is visible" and offsetParent are the same ???? comment is off
There was a problem hiding this comment.
offsetParent is null when an element is invisible 😉
There was a problem hiding this comment.
I know clientHeight\Width are 0 when invisible (makes sense), but didn't know about offsetParent (less obvious). I would sue that (which matches your comment)
| }; | ||
| } | ||
|
|
||
| /** @internal TODO: set to public as called by DDDroppable! */ |
There was a problem hiding this comment.
you've ppossibly changed the meaning of DDUIData here, yet this is used by DDDroppable according to comment, and I don't see changes in this review.... did you follow through and see how it is used and if this might be a breaking change ?
There was a problem hiding this comment.
It's still the position of the helper 🤔
| const containerElement = Utils.getPositionContainerElement(this.el.parentElement); | ||
| const containerRect = containerElement.getBoundingClientRect(); | ||
|
|
||
| const newRect = { // Note: originalRect is a complex object, not a simple Rect, so copy out. |
There was a problem hiding this comment.
to be honest I don't know _getChange() is used anymore...
There was a problem hiding this comment.
Yes it is. It is actually all the logic of the resize. It's called every time we resize
| const minHeight = this.option.minHeight || oHeight; | ||
| const { scaleX, scaleY } = Utils.getScaleForElement(this.el); | ||
| const o = this.option; | ||
| const maxWidth = o.maxWidth ? o.maxWidth * scaleX : Number.MAX_SAFE_INTEGER; |
There was a problem hiding this comment.
if I recall this.options.maxWidth = n.maxW * cellWidth, so they still need to be scalled ?
There was a problem hiding this comment.
Yes because the scale apply to the grid so if the cell are 10px and you scale to 2 you will have actual cell of 20px
| this.el.style[key] = value - containmentRect[key] + 'px'; | ||
| }); | ||
| const { scaleX, scaleY } = Utils.getScaleForElement(this.el); | ||
| this.el.style.width = `${Math.floor(this.temporalRect.width / scaleX)}px`; |
There was a problem hiding this comment.
why floor() and not round() ? if I recall you didn't have anyhting before and claimed all was working. what changed ?
There was a problem hiding this comment.
Nothing floor was working that's it. I can do round to
3e2f7c8 to
41a3da3
Compare
|
Back to you @adumesny 😉 |
|
still broken... while main demos seem fine (two.html and nested.html) offset.html doesn't work now. 20230904_175826.mp4 |
|
The refacto did introduce a bug on the |
|
@adumesny can you take a look at it 👼 ? |
|
swamped at work and can't this weekend... I'll try to find time. |
|
great, I tested a bunch of examples and mobile and it's working now. Will commit and go over the code again. thanks. |
…n element (gridstack#2263)" re-opens gridstack#1275, and fix gridstack#2498 gridstack#2497 gridstack#2491 This reverts commit b559a6f.
…n element (gridstack#2263)" re-opens gridstack#1275, and fix gridstack#2498 gridstack#2497 gridstack#2491 This reverts commit b559a6f.
gridstack#2263) * fix(drag): place the element dragged always below the mouse * fix: review fixes * fix: fix data transfer demo * fix: review fixes * fix: fix position according to first transform parent * review fixes * review fixes * review fixes * fix: fix the refacto --------- Co-authored-by: Vincent Molinié <vincent.m@forestadmin.com>



Description
The position of elements dragged was badly calculated and resulted in weird behaviour in a lot of cases like:
scalecss property and try to drag a componentChecklist
yarn test)Issues fixed
#1275