@qnc/drag_sorter
v0.4.1
Published
Work-in-progress
Readme
DEPRECATED. Use @qnc/drag_sorter2, instead
drag_sorter2 is intended to replace drag_sorter, but you can have both installed. drag_sorter chose an unfortunate "swapping approach" when moving a child around in a 2-D layout. drag_sorter2 uses the conventional approach (sibling elements retain respective order). The change in approach also necessitated a change in the callback signatures.
Important points
- you can only reorder children of a single element
- works on all current AND future children of the parent (ie. you can add children after making the parent sortable, and those children will also be draggable)
- works with horizontal, vertical, or 2-D layouts
- original element is set to "visibility: hidden" while being dragged (to leave a space)
- we clone the element, and that's what you drag around
- the clone is appended to the parent, with z-index 1; it's up to you to ensure this stacks properly on your page
- you probably want to set "cursor: grab" on your draggable elements; we set "cursor: grabbing" WHILE dragging
Swapping/sorting algorithm (NOT GOOD)
When dragging an element in some type of grid layout, there are multiple algorithms one could use. SortableJS, for example, will relocate ONLY the dragged element; the other siblings will always maintain their respective order. This equivalent to saying that the dragged element may only ever "swap" with its previous or next sibling (consective swaps may move the dragged element multiple positions, but all other siblings maintain their ordering).
We take another approach. The dragged element may "swap", in a single move, with any of it's sibling elements.
These two algorithms produce notably different effects when dragging an element in a sortable grid layout.
Our "swapping" algorithm is considered part of our contract. We will never switch to the SortableJS approach. We may, however, add an option so that you can opt-in to the SortableJS approach.
Aargh! I regret choosing this as the default algorithm. It can "push" siblings around in unexpected ways. It can be neat for a "let's play and move things around" type for interface, but it's not good for a SORTING interface (where you want to be able to pick up X and move it within the list without messing up the order of other items).
TODO/Ideas
- animate into final position on release (shouldn't bee too bad)
- animate sibling swaps (fairly difficult)
- touch screen support (might already be done???)
Unstable swaps / thrashing
When dragging a small element over a larger element, you can end up with an unstable position where the two siblings keep swapping back and forth. Need to fix this! It would probably be sufficient to say that the dot_product(movement_vector, sibling_vector) must be greater than HSL, rather than HSL/2. This makes swaps happen "later". This might lead to situations where it's difficult to move an element to the beginning or end of the list. I think the ideal algorithm is: - compute drag-child's center - compute drag-child's "projected center" (if we were to swap) - let midpoint = midpoint(current center, projected center) - swap with sibling IFF we've moved "past" the midpoint (reduces to the same as the current algorithm when siblings have equal size)
Computing "projected center" is likely impossible, however, without actually swapping and resetting
Usage
npm install --save-dev @qnc/drag_sorterimport {enable, disable} from "@qnc/drag_sorter- use something like esbuild to build your app
Reminder: we've included drag_sorter.d.ts (typescript definition file), so you can import from typescript with full support, but the module is pre-built, so you don't need to use typescript compiler when building/bundling.
