-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdraggables.js
More file actions
137 lines (109 loc) · 3 KB
/
Copy pathdraggables.js
File metadata and controls
137 lines (109 loc) · 3 KB
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
let dragTarget = undefined;
let draggables = new Array();
const promoteZIndex = (id) => {
// Shuffle everyone who was above me, down 1.
draggables = draggables.sort((a, b) => {
return a.zIndex - b.zIndex;
});
const elementIndex = draggables.findIndex((d) => d.id === id);
draggables.slice(elementIndex + 1).forEach((draggable) => {
draggable.zIndex = draggable.zIndex - 1;
});
// Raise Z-index of this element to top of stack
draggables[elementIndex].zIndex = draggables.length - 1;
applyZIndicies();
};
const findWindowByClickAndPromote = (element) => {
if (!element.parentElement) {
return;
}
const classList = element.classList;
if (!classList.contains("draggable")) {
return findWindowByClickAndPromote(element.parentElement);
}
if (!element.id) {
return;
}
promoteZIndex(element.id);
};
const applyZIndicies = () => {
draggables.forEach((d) => {
targetIndex = d.zIndex + WINDOW_Z_INDEX_STACK_START;
d.element.style.zIndex = targetIndex;
});
};
// Handle ongoing drags
window.addEventListener("mousemove", () => {
if (dragTarget) {
if (!dragging) {
dragging = true;
startX = event.clientX;
startY = event.clientY;
promoteZIndex(dragTarget.id);
} else {
let diffX = startX - event.clientX;
let diffY = startY - event.clientY;
let newLeft = dragTarget.style.left.split("px")[0] - diffX;
let newTop = dragTarget.style.top.split("px")[0] - diffY;
dragTarget.style.left = `${newLeft}px`;
dragTarget.style.top = `${newTop}px`;
startX = event.clientX;
startY = event.clientY;
}
}
});
window.addEventListener("click", (event) => {
const target = event.target;
if (!target) {
return;
}
findWindowByClickAndPromote(target);
});
// Stop drag if in progress
window.addEventListener("mouseup", () => {
dragTarget = undefined;
dragging = false;
});
window.addEventListener("load", () => {
draggables = Array.from(document.querySelectorAll(".draggable")).map((element, index) => {
const defaults = WINDOW_DEFAULTS[element.id];
return {
open: false,
id: element.id,
element,
zIndex: index,
...defaults,
};
});
draggables.forEach((draggable) => {
let header = draggable.element.children[0].children[0];
header.addEventListener("mousedown", (event) => {
if (event.buttons & 1) {
dragTarget = draggable.element;
}
});
});
processDraggables();
});
const setWindowVisibility = (id, visibility) => {
const draggable = draggables.find((d) => d.id === id);
draggable.open = visibility;
promoteZIndex(draggable.id);
processDraggables();
};
const processDraggables = () => {
draggables.forEach((d) => {
processDraggable(d);
});
applyZIndicies();
};
const processDraggable = (draggable) => {
if (draggable.open) {
draggable.element.style.visibility = "visible";
} else {
draggable.element.style.visibility = "hidden";
}
};
let dragging = false;
let startX = 0;
let startY = 0;