React-beautiful-dnd: Dynamically change the reference point when dragging

Created on 20 May 2018  ·  14Comments  ·  Source: atlassian/react-beautiful-dnd

Bug or feature request?

Feature request


I saw that in the examples the draggables has much the same widths/heights. I'm trying to use the API in a vertical list, but with longer and shorter elements too. I realized that if an element is dragging, the order gets changing if the actual draggable's center reaches the draggable's border next to it. It looks a bit disappointing if the draggable which is dragging a much longer element than it's "siblings". My idea is that if the dragging was started, check the draggable's width, and check the elements width which are next to it. If the actual element's width is shorter than the element which is next to them, the reference point is the actual element's center. If the actual element's width is longer than the next element, set the reference point to the element's center which is next to the actual element.

Expected behavior

Actual behavior

Steps to reproduce

Browser version

Demo

improvement ⭐️ investigating 🕵️‍♂️ high 🔥

Most helpful comment

In addition, if start dragging between different widths of the droppable containers. When dragging from a wider to a narrower droppable, the center of the dragged element is expected. It not look obvious. Does there is possibility for dropping element, if dragging cursor was over dropping container?

All 14 comments

We have put a lot of time into creating an experience that works well regardless of item size as well as the sizes of the other items in the list:

https://github.com/atlassian/react-beautiful-dnd#application-2-knowing-when-to-move

Application 2: knowing when to move
It is quite common for drag and drop interactions to be based on the position that user started the drag from.
In react-beautiful-dnd a dragging items impact is based on its centre of gravity — regardless of where a user grabs an item from. A dragging items impact follows similar rules to a set of scales ⚖️. Here are some rules that are followed to allow for a natural drag experience even with items of flexible height:

  • A list is dragged over when the centre position of a dragging item goes over one of the boundaries of the list
  • A resting drag item will move out of the way of a dragging item when the centre position of the dragging item goes over the edge of the resting item. Put another way: once the centre position of an item (A) goes over the edge of another item (B), B moves out of the way.

This is enforced provide a consistant and natural experience. Are you proposing an enhancement to this?

horizontal list - codesandbox - google chrome 2018 05 21 11_49_51_4
What i want to earn, is this. Toggle the method of when the (A) is shorter than (B), the (B) moves out the way if the (A)'s center goes over (B)'s edge, if the (A) is longer than (B), the (B) moves out the way if the (A)'s edge (left or right depending on which side of (A) is (B)) goes over (B)'s center. If the way i was shown isn't matches with the application, i will be very happy (if there's a way to do this) if you show me, how can i earn this.

This looks like a really interesting enhancement

In addition, if start dragging between different widths of the droppable containers. When dragging from a wider to a narrower droppable, the center of the dragged element is expected. It not look obvious. Does there is possibility for dropping element, if dragging cursor was over dropping container?

How to move a 1000px draggable element to a 300px droppable container if that is at the edge of the page? (Looks like draggable between different types, but it's need.)

2222

We do not use the selection position because:

  • It goes against the physical metaphor we are going for (all impacts are based on the items centre of gravity)
  • Using the selection point also has troubles. If a user grabs something in an inconvenient spot then they may also be unable to move the thing into the right place.

I am keen not to get distracted from your original suggestion in this issue. Please create other issues if you think there are other parts of the library that are worth discussing.

Cheers

I have not forgotten about this one!

The logic for this would need to be direction aware. It looks like we are adding some internal logic that could make this change possible

It turns out we need to get this right in order for #511 to work correctly.

I currently have this working in home lists, I am now looking into foreign lists

Any news on that topic?

This will be shipping in #719. I'll keep this open until that ships

Going out in #838

It seems like there still is some problems with dragging behavior in lists with uneqally sized draggables.

Expected behavior
An element "A" should move up or down across the element that is being dragged,"B", when the (upper or lower) border of B crosses the center of A.
This would be opposite of how draggables moved, before version 10:

A resting drag item will move out of the way of a dragging item when the centre position of the dragging item goes over the edge of the resting item. Put another way: once the centre position of an item (A) goes over the edge of another item (B), B moves out of the way.

So, instead of letting the break point be: _Center of dragged item hits edge of resting item_ (meaning a large item could cover several smaller items before they reach the center),
I suggest the break point is: _Edge of dragged item hits center of resting item_.
With this behavior resting items would never be covered more than 50% by the item being dragged, no matter their size. Items would also land as close as possible to where they are dropped, which currently is not always the case.
In a list with elements of equal size the behavior would be similar to what it is now, and in lists with different sized elements the behavior would be more natural.

Actual behavior
The current logic gives behavior like this
long_drag

Smaller elements slide over bigger ones immediately, it would be more natural that they snap across the element when they are dragged half way over.
short_drag

ignoreContainerClipping={true}
For <Droppable />

Was this page helpful?
0 / 5 - 0 ratings

Related issues

h182032 picture h182032  ·  3Comments

heymartinadams picture heymartinadams  ·  3Comments

screenmeet picture screenmeet  ·  3Comments

khurram-wasim picture khurram-wasim  ·  3Comments

lukyth picture lukyth  ·  3Comments