-
-
Notifications
You must be signed in to change notification settings - Fork 26
/
Copy pathcore-dragging.ts
93 lines (81 loc) · 2.68 KB
/
core-dragging.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import { SyntheticEvent } from "react";
import { ISpaceDefinition, ISpaceStore, EndEvent, MoveEvent, OnDragEnd } from "./core-types";
import { throttle } from "./core-utils";
export function createDrag(store: ISpaceStore) {
function onMove(space: ISpaceDefinition, originalX: number, originalY: number, x: number, y: number) {
const adjustmentX = -(originalX - x);
const adjustmentY = -(originalY - y);
space.left.adjusted = [adjustmentX];
space.top.adjusted = [adjustmentY];
if (space.right.size) {
space.right.adjusted = [-adjustmentX];
}
if (space.bottom.size) {
space.bottom.adjusted = [-adjustmentY];
}
store.updateStyles(space);
}
return {
startDrag<T extends SyntheticEvent<HTMLElement> | MouseEvent | TouchEvent>(
e: T,
space: ISpaceDefinition,
endEvent: EndEvent,
moveEvent: MoveEvent,
getCoords: (event: T) => { x: number; y: number },
onDragEnd?: OnDragEnd,
) {
if (space.element) {
const coords = getCoords(e);
const adjustedLeft = space.left.adjusted.length === 0 ? 0 : (space.left.adjusted[0] as number);
const adjustedTop = space.top.adjusted.length === 0 ? 0 : (space.top.adjusted[0] as number);
const originalMouseX = coords.x - adjustedLeft;
const originalMouseY = coords.y - adjustedTop;
let lastX = 0;
let lastY = 0;
let moved = false;
const mouseMove = (x: number, y: number) => onMove(space, originalMouseX, originalMouseY, x, y);
const throttledMouseMove = throttle<typeof mouseMove>(mouseMove, 5);
const withPreventDefault = (e: T) => {
moved = true;
const newCoords = getCoords(e);
lastX = newCoords.x;
lastY = newCoords.y;
e.preventDefault();
throttledMouseMove(lastX, lastY);
};
const removeListener = () => {
if (moved) {
mouseMove(lastX, lastY);
}
window.removeEventListener(moveEvent, withPreventDefault as EventListener);
window.removeEventListener(endEvent, removeListener);
if (onDragEnd) {
const parentInfo = (space.parentId && store.getSpace(space.parentId)?.element.getBoundingClientRect()) || {
left: 0,
top: 0,
right: 0,
bottom: 0,
width: 0,
height: 0,
};
const info = (({ left, top, right, bottom, width, height }) => ({ left, top, right, bottom, width, height }))(
space.element.getBoundingClientRect(),
);
onDragEnd(
{
...info,
...{
left: info.left - parentInfo.left,
top: info.top - parentInfo.top,
},
},
moved,
);
}
};
window.addEventListener(moveEvent, withPreventDefault as EventListener);
window.addEventListener(endEvent, removeListener);
}
},
};
}