Skip to content

Commit c54e509

Browse files
authored
A new collision engine (#1638)
2 parents cf5c727 + 5f43206 commit c54e509

File tree

73 files changed

+2428
-2000
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+2428
-2000
lines changed

.size-snapshot.json

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
11
{
22
"dist/react-beautiful-dnd.js": {
3-
"bundled": 381298,
4-
"minified": 140093,
5-
"gzipped": 42104
3+
"bundled": 379875,
4+
"minified": 139571,
5+
"gzipped": 41966
66
},
77
"dist/react-beautiful-dnd.min.js": {
8-
"bundled": 322912,
9-
"minified": 115528,
10-
"gzipped": 34201
8+
"bundled": 321489,
9+
"minified": 115006,
10+
"gzipped": 34084
1111
},
1212
"dist/react-beautiful-dnd.esm.js": {
13-
"bundled": 242417,
14-
"minified": 126431,
15-
"gzipped": 32987,
13+
"bundled": 241086,
14+
"minified": 125714,
15+
"gzipped": 32875,
1616
"treeshaked": {
1717
"rollup": {
18-
"code": 21303,
18+
"code": 21306,
1919
"import_statements": 788
2020
},
2121
"webpack": {
22-
"code": 24960
22+
"code": 24963
2323
}
2424
}
2525
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-beautiful-dnd",
3-
"version": "12.1.1",
3+
"version": "12.2.0-alpha.1",
44
"description": "Beautiful and accessible drag and drop for lists with React",
55
"author": "Alex Reardon <areardon@atlassian.com>",
66
"keywords": [

src/state/calculate-drag-impact/calculate-combine-impact.js

Lines changed: 0 additions & 64 deletions
This file was deleted.
Lines changed: 79 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -1,148 +1,130 @@
11
// @flow
2-
import type { Rect, Position } from 'css-box-model';
2+
import type { Rect } from 'css-box-model';
33
import type {
44
DraggableId,
55
Axis,
6-
UserDirection,
76
DraggableDimension,
87
DroppableDimension,
9-
CombineImpact,
108
DragImpact,
11-
DisplacementGroups,
129
LiftEffect,
1310
DisplacedBy,
1411
} from '../../types';
15-
import isWithin from '../is-within';
1612
import { find } from '../../native-with-fallback';
17-
import isUserMovingForward from '../user-direction/is-user-moving-forward';
18-
import getCombinedItemDisplacement from '../get-combined-item-displacement';
19-
import removeDraggableFromList from '../remove-draggable-from-list';
20-
import calculateCombineImpact from '../calculate-drag-impact/calculate-combine-impact';
13+
import getDidStartAfterCritical from '../did-start-after-critical';
2114
import getDisplacedBy from '../get-displaced-by';
22-
23-
function getWhenEntered(
24-
id: DraggableId,
25-
current: UserDirection,
26-
lastCombineImpact: ?CombineImpact,
27-
): UserDirection {
28-
if (!lastCombineImpact) {
29-
return current;
30-
}
31-
if (id !== lastCombineImpact.combine.draggableId) {
32-
return current;
33-
}
34-
return lastCombineImpact.whenEntered;
35-
}
36-
37-
type IsCombiningWithArgs = {|
38-
id: DraggableId,
39-
currentCenter: Position,
40-
axis: Axis,
41-
borderBox: Rect,
42-
displaceBy: Position,
43-
currentUserDirection: UserDirection,
44-
lastCombineImpact: ?CombineImpact,
45-
|};
46-
47-
const isCombiningWith = ({
48-
id,
49-
currentCenter,
50-
axis,
51-
borderBox,
52-
displaceBy,
53-
currentUserDirection,
54-
lastCombineImpact,
55-
}: IsCombiningWithArgs): boolean => {
56-
const start: number = borderBox[axis.start] + displaceBy[axis.line];
57-
const end: number = borderBox[axis.end] + displaceBy[axis.line];
58-
const size: number = borderBox[axis.size];
59-
const twoThirdsOfSize: number = size * 0.666;
60-
61-
const whenEntered: UserDirection = getWhenEntered(
62-
id,
63-
currentUserDirection,
64-
lastCombineImpact,
65-
);
66-
const isMovingForward: boolean = isUserMovingForward(axis, whenEntered);
67-
const targetCenter: number = currentCenter[axis.line];
68-
69-
if (isMovingForward) {
70-
// combine when moving in the front 2/3 of the item
71-
return isWithin(start, start + twoThirdsOfSize)(targetCenter);
72-
}
73-
// combine when moving in the back 2/3 of the item
74-
return isWithin(end - twoThirdsOfSize, end)(targetCenter);
75-
};
76-
77-
function tryGetCombineImpact(impact: DragImpact): ?CombineImpact {
78-
if (impact.at && impact.at.type === 'COMBINE') {
79-
return impact.at;
80-
}
81-
return null;
82-
}
15+
import getIsDisplaced from '../get-is-displaced';
16+
import removeDraggableFromList from '../remove-draggable-from-list';
8317

8418
type Args = {|
8519
draggable: DraggableDimension,
86-
pageBorderBoxCenterWithDroppableScrollChange: Position,
20+
pageBorderBoxWithDroppableScroll: Rect,
8721
previousImpact: DragImpact,
8822
destination: DroppableDimension,
8923
insideDestination: DraggableDimension[],
90-
userDirection: UserDirection,
9124
afterCritical: LiftEffect,
9225
|};
26+
27+
// exported for testing
28+
export const combineThresholdDivisor: number = 4;
29+
9330
export default ({
9431
draggable,
95-
pageBorderBoxCenterWithDroppableScrollChange: currentCenter,
32+
pageBorderBoxWithDroppableScroll: targetRect,
9633
previousImpact,
9734
destination,
9835
insideDestination,
99-
userDirection,
10036
afterCritical,
10137
}: Args): ?DragImpact => {
10238
if (!destination.isCombineEnabled) {
10339
return null;
10440
}
105-
10641
const axis: Axis = destination.axis;
107-
const displaced: DisplacementGroups = previousImpact.displaced;
108-
const canBeDisplacedBy: DisplacedBy = getDisplacedBy(
42+
const displacedBy: DisplacedBy = getDisplacedBy(
10943
destination.axis,
11044
draggable.displaceBy,
11145
);
112-
const lastCombineImpact: ?CombineImpact = tryGetCombineImpact(previousImpact);
46+
const displacement: number = displacedBy.value;
47+
48+
const targetStart: number = targetRect[axis.start];
49+
const targetEnd: number = targetRect[axis.end];
50+
51+
const withoutDragging: DraggableDimension[] = removeDraggableFromList(
52+
draggable,
53+
insideDestination,
54+
);
11355

11456
const combineWith: ?DraggableDimension = find(
115-
removeDraggableFromList(draggable, insideDestination),
57+
withoutDragging,
11658
(child: DraggableDimension): boolean => {
11759
const id: DraggableId = child.descriptor.id;
60+
const childRect: Rect = child.page.borderBox;
61+
const childSize: number = childRect[axis.size];
62+
const threshold: number = childSize / combineThresholdDivisor;
11863

119-
const displaceBy: Position = getCombinedItemDisplacement({
120-
displaced,
64+
const didStartAfterCritical: boolean = getDidStartAfterCritical(
65+
id,
12166
afterCritical,
122-
combineWith: id,
123-
displacedBy: canBeDisplacedBy,
124-
});
67+
);
12568

126-
return isCombiningWith({
69+
const isDisplaced: boolean = getIsDisplaced({
70+
displaced: previousImpact.displaced,
12771
id,
128-
currentCenter,
129-
axis,
130-
borderBox: child.page.borderBox,
131-
displaceBy,
132-
currentUserDirection: userDirection,
133-
lastCombineImpact,
13472
});
73+
74+
/*
75+
Only combining when in the combine region
76+
As soon as a boundary is hit then no longer combining
77+
*/
78+
79+
if (didStartAfterCritical) {
80+
// In original position
81+
// Will combine with item when inside a band
82+
if (isDisplaced) {
83+
return (
84+
targetEnd > childRect[axis.start] + threshold &&
85+
targetEnd < childRect[axis.end] - threshold
86+
);
87+
}
88+
89+
// child is now 'displaced' backwards from where it started
90+
// want to combine when we move backwards onto it
91+
return (
92+
targetStart > childRect[axis.start] - displacement + threshold &&
93+
targetStart < childRect[axis.end] - displacement - threshold
94+
);
95+
}
96+
97+
// item has moved forwards
98+
if (isDisplaced) {
99+
return (
100+
targetEnd > childRect[axis.start] + displacement + threshold &&
101+
targetEnd < childRect[axis.end] + displacement - threshold
102+
);
103+
}
104+
105+
// is in resting position - being moved backwards on to
106+
return (
107+
targetStart > childRect[axis.start] + threshold &&
108+
targetStart < childRect[axis.end] - threshold
109+
);
135110
},
136111
);
137112

138113
if (!combineWith) {
139114
return null;
140115
}
141116

142-
return calculateCombineImpact({
143-
combineWithId: combineWith.descriptor.id,
144-
destinationId: destination.descriptor.id,
145-
previousImpact,
146-
userDirection,
147-
});
117+
const impact: DragImpact = {
118+
// no change to displacement when combining
119+
displacedBy,
120+
displaced: previousImpact.displaced,
121+
at: {
122+
type: 'COMBINE',
123+
combine: {
124+
draggableId: combineWith.descriptor.id,
125+
droppableId: destination.descriptor.id,
126+
},
127+
},
128+
};
129+
return impact;
148130
};

0 commit comments

Comments
 (0)